home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / dix / events.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-28  |  87.2 KB  |  3,350 lines

  1. /************************************************************
  2. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  3. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its 
  8. documentation for any purpose and without fee is hereby granted, 
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in 
  11. supporting documentation, and that the names of Digital or MIT not be
  12. used in advertising or publicity pertaining to distribution of the
  13. software without specific, written prior permission.  
  14.  
  15. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  16. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  17. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  18. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  19. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  20. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21. SOFTWARE.
  22.  
  23. ********************************************************/
  24.  
  25.  
  26. /* $XConsortium: events.c,v 5.22 90/03/08 11:27:15 rws Exp $ */
  27.  
  28. #include "X.h"
  29. #include "misc.h"
  30. #include "resource.h"
  31. #define NEED_EVENTS
  32. #define NEED_REPLIES
  33. #include "Xproto.h"
  34. #include "windowstr.h"
  35. #include "inputstr.h"
  36. #include "scrnintstr.h"
  37. #include "cursorstr.h"
  38.  
  39. #include "dixstruct.h"
  40.  
  41. #undef sprite    /* there is a variable called "sprite" in this file... */
  42.  
  43. extern WindowPtr *WindowTable;
  44.  
  45. extern void (* EventSwapVector[128]) ();
  46. extern void (* ReplySwapVector[256]) ();
  47. extern void SetCriticalOutputPending();
  48.  
  49. #define EXTENSION_EVENT_BASE  64
  50.  
  51. #define NoSuchEvent 0x80000000    /* so doesn't match NoEventMask */
  52. #define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
  53. #define AllButtonsMask ( \
  54.     Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
  55. #define MotionMask ( \
  56.     PointerMotionMask | Button1MotionMask | \
  57.     Button2MotionMask | Button3MotionMask | Button4MotionMask | \
  58.     Button5MotionMask | ButtonMotionMask )
  59. #define PropagateMask ( \
  60.     KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
  61.     MotionMask )
  62. #define PointerGrabMask ( \
  63.     ButtonPressMask | ButtonReleaseMask | \
  64.     EnterWindowMask | LeaveWindowMask | \
  65.     PointerMotionHintMask | KeymapStateMask | \
  66.     MotionMask )
  67. #define AllModifiersMask ( \
  68.     ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
  69.     Mod3Mask | Mod4Mask | Mod5Mask )
  70. #define AllEventMasks (lastEventMask|(lastEventMask-1))
  71. /*
  72.  * The following relies on the fact that the Button<n>MotionMasks are equal
  73.  * to the corresponding Button<n>Masks from the current modifier/button state.
  74.  */
  75. #define Motion_Filter(class) (PointerMotionMask | \
  76.                   (class)->state | (class)->motionMask)
  77.  
  78.  
  79. #define WID(w) ((w) ? ((w)->drawable.id) : 0)
  80.  
  81. #define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
  82.  
  83. #define DNPMCOUNT 8
  84.  
  85. Mask DontPropagateMasks[DNPMCOUNT];
  86. static int DontPropagateRefCnts[DNPMCOUNT];
  87.  
  88. #ifdef DEBUG
  89. static debug_events = 0;
  90. #endif
  91. InputInfo inputInfo;
  92.  
  93. static struct {
  94.     QdEventPtr        pending, *pendtail;
  95.     DeviceIntPtr    replayDev;    /* kludgy rock to put flag for */
  96.     WindowPtr        replayWin;    /*   ComputeFreezes            */
  97.     Bool        playingEvents;
  98.     TimeStamp        time;
  99. } syncEvents;
  100.  
  101. /*
  102.  * The window trace information is used to avoid having to compute all the
  103.  * windows between the root and the current pointer window each time a button
  104.  * or key goes down. The grabs on each of those windows must be checked.
  105.  */
  106. static WindowPtr *spriteTrace = (WindowPtr *)NULL;
  107. #define ROOT spriteTrace[0]
  108. static int spriteTraceSize = 0;
  109. static int spriteTraceGood;
  110.  
  111. typedef struct {
  112.     int        x, y;
  113.     ScreenPtr    pScreen;
  114. } HotSpot;
  115.  
  116. static  struct {
  117.     CursorPtr    current;
  118.     BoxRec    hotLimits;    /* logical constraints of hot spot */
  119. #ifdef SHAPE
  120.     RegionPtr    hotShape;    /* additional logical shape constraint */
  121. #endif
  122.     BoxRec    physLimits;    /* physical constraints of hot spot */
  123.     WindowPtr    win;        /* window of logical position */
  124.     HotSpot    hot;        /* logical pointer position */
  125.     HotSpot    hotPhys;    /* physical pointer position */
  126. } sprite;            /* info about the cursor sprite */
  127.  
  128. static void DoEnterLeaveEvents();    /* merely forward declarations */
  129. static WindowPtr XYToWindow();
  130. void DeliverFocusedEvent();
  131. int DeliverDeviceEvents();
  132. void DoFocusEvents();
  133. Mask EventMaskForClient();
  134. void WriteEventsToClient();
  135. Bool CheckDeviceGrabs();
  136. void NewCurrentScreen();
  137. static void EnqueueEvent();
  138.  
  139. extern void MaybeStopHint();
  140.  
  141. extern GrabPtr CreateGrab();        /* Defined in grabs.c */
  142. extern Bool GrabMatchesSecond();
  143. extern Bool DeletePassiveGrabFromList();
  144. extern int AddPassiveGrabToList();
  145.  
  146. extern Bool permitOldBugs;
  147.  
  148. static Mask lastEventMask;
  149.  
  150. #define CantBeFiltered NoEventMask
  151. static Mask filters[128] =
  152. {
  153.     NoSuchEvent,               /* 0 */
  154.     NoSuchEvent,               /* 1 */
  155.     KeyPressMask,               /* KeyPress */
  156.     KeyReleaseMask,               /* KeyRelease */
  157.     ButtonPressMask,           /* ButtonPress */
  158.     ButtonReleaseMask,           /* ButtonRelease */
  159.     PointerMotionMask,           /* MotionNotify (initial state) */
  160.     EnterWindowMask,           /* EnterNotify */
  161.     LeaveWindowMask,           /* LeaveNotify */
  162.     FocusChangeMask,           /* FocusIn */
  163.     FocusChangeMask,           /* FocusOut */
  164.     KeymapStateMask,           /* KeymapNotify */
  165.     ExposureMask,               /* Expose */
  166.     CantBeFiltered,               /* GraphicsExpose */
  167.     CantBeFiltered,               /* NoExpose */
  168.     VisibilityChangeMask,           /* VisibilityNotify */
  169.     SubstructureNotifyMask,           /* CreateNotify */
  170.     StructureAndSubMask,           /* DestroyNotify */
  171.     StructureAndSubMask,           /* UnmapNotify */
  172.     StructureAndSubMask,           /* MapNotify */
  173.     SubstructureRedirectMask,      /* MapRequest */
  174.     StructureAndSubMask,           /* ReparentNotify */
  175.     StructureAndSubMask,           /* ConfigureNotify */
  176.     SubstructureRedirectMask,      /* ConfigureRequest */
  177.     StructureAndSubMask,           /* GravityNotify */
  178.     ResizeRedirectMask,           /* ResizeRequest */
  179.     StructureAndSubMask,           /* CirculateNotify */
  180.     SubstructureRedirectMask,      /* CirculateRequest */
  181.     PropertyChangeMask,           /* PropertyNotify */
  182.     CantBeFiltered,               /* SelectionClear */
  183.     CantBeFiltered,               /* SelectionRequest */
  184.     CantBeFiltered,               /* SelectionNotify */
  185.     ColormapChangeMask,           /* ColormapNotify */
  186.     CantBeFiltered,               /* ClientMessage */
  187.     CantBeFiltered               /* MappingNotify */
  188. };
  189.  
  190. static CARD8 criticalEvents[32] =
  191. {
  192.     0x3c                /* key and button events */
  193. };
  194.  
  195. Mask
  196. GetNextEventMask()
  197. {
  198.     lastEventMask <<= 1;
  199.     return lastEventMask;
  200. }
  201.  
  202. void
  203. SetMaskForEvent(mask, event)
  204.     Mask mask;
  205.     int event;
  206. {
  207.     if ((event < LASTEvent) || (event >= 128))
  208.     FatalError("SetMaskForEvent: bogus event number");
  209.     filters[event] = mask;
  210. }
  211.  
  212. void
  213. SetCriticalEvent(event)
  214.     int event;
  215. {
  216.     if (event >= 128)
  217.     FatalError("SetCriticalEvent: bogus event number");
  218.     criticalEvents[event >> 3] |= 1 << (event & 7);
  219. }
  220.  
  221. static void
  222. SyntheticMotion(x, y)
  223.     int x, y;
  224. {
  225.     xEvent xE;
  226.  
  227.     xE.u.keyButtonPointer.rootX = x;
  228.     xE.u.keyButtonPointer.rootY = y;
  229.     if (syncEvents.playingEvents)
  230.     xE.u.keyButtonPointer.time = syncEvents.time.milliseconds;
  231.     else
  232.     xE.u.keyButtonPointer.time = currentTime.milliseconds;
  233.     xE.u.u.type = MotionNotify;
  234.     (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1);
  235. }
  236.  
  237. #ifdef SHAPE
  238. static void
  239. ConfineToShape(shape, px, py)
  240.     RegionPtr shape;
  241.     int *px, *py;
  242. {
  243.     BoxRec box;
  244.     int x = *px, y = *py;
  245.     int incx = 1, incy = 1;
  246.  
  247.     if ((*sprite.hot.pScreen->PointInRegion)(shape, x, y, &box))
  248.     return;
  249.     box = *(*sprite.hot.pScreen->RegionExtents)(shape);
  250.     /* this is rather crude */
  251.     do {
  252.     x += incx;
  253.     if (x >= box.x2)
  254.     {
  255.         incx = -1;
  256.         x = *px - 1;
  257.     }
  258.     else if (x < box.x1)
  259.     {
  260.         incx = 1;
  261.         x = *px;
  262.         y += incy;
  263.         if (y >= box.y2)
  264.         {
  265.         incy = -1;
  266.         y = *py - 1;
  267.         }
  268.         else if (y < box.y1)
  269.         return; /* should never get here! */
  270.     }
  271.     } while (!(*sprite.hot.pScreen->PointInRegion)(shape, x, y, &box));
  272.     *px = x;
  273.     *py = y;
  274. }
  275. #endif
  276.  
  277. static void
  278. CheckPhysLimits(cursor, generateEvents, pScreen)
  279.     CursorPtr cursor;
  280.     Bool generateEvents;
  281.     ScreenPtr pScreen;
  282. {
  283.     HotSpot new;
  284.  
  285.     if (!cursor)
  286.     return;
  287.     new = sprite.hotPhys;
  288.     if (pScreen)
  289.     new.pScreen = pScreen;
  290.     else
  291.     pScreen = new.pScreen;
  292.     (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits,
  293.                   &sprite.physLimits);
  294.     if (new.x < sprite.physLimits.x1)
  295.     new.x = sprite.physLimits.x1;
  296.     else
  297.     if (new.x >= sprite.physLimits.x2)
  298.         new.x = sprite.physLimits.x2 - 1;
  299.     if (new.y < sprite.physLimits.y1)
  300.     new.y = sprite.physLimits.y1;
  301.     else
  302.     if (new.y >= sprite.physLimits.y2)
  303.         new.y = sprite.physLimits.y2 - 1;
  304. #ifdef SHAPE
  305.     if (sprite.hotShape)
  306.     ConfineToShape(sprite.hotShape, &new.x, &new.y);
  307. #endif
  308.     if ((pScreen != sprite.hotPhys.pScreen) ||
  309.     (new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
  310.     {
  311.     if (pScreen != sprite.hotPhys.pScreen)
  312.         sprite.hotPhys = new;
  313.     (*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents);
  314.     if (!generateEvents)
  315.         SyntheticMotion(new.x, new.y);
  316.     }
  317. }
  318.  
  319. static void
  320. CheckVirtualMotion(qe, pWin)
  321.     register QdEventPtr qe;
  322.     register WindowPtr pWin;
  323. {
  324.  
  325.     if (qe)
  326.     {
  327.     sprite.hot.pScreen = qe->pScreen;
  328.     sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
  329.     sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
  330.     pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
  331.                      NullWindow;
  332.     }
  333.     if (pWin)
  334.     {
  335.     BoxRec lims;
  336.  
  337.     if (sprite.hot.pScreen != pWin->drawable.pScreen)
  338.     {
  339.         sprite.hot.pScreen = pWin->drawable.pScreen;
  340.         sprite.hot.x = sprite.hot.y = 0;
  341.     }
  342.     lims = *(*pWin->drawable.pScreen->RegionExtents)(&pWin->borderSize);
  343.     if (sprite.hot.x < lims.x1)
  344.         sprite.hot.x = lims.x1;
  345.     else if (sprite.hot.x >= lims.x2)
  346.         sprite.hot.x = lims.x2 - 1;
  347.     if (sprite.hot.y < lims.y1)
  348.         sprite.hot.y = lims.y1;
  349.     else if (sprite.hot.y >= lims.y2)
  350.         sprite.hot.y = lims.y2 - 1;
  351. #ifdef SHAPE
  352.     if (wBoundingShape(pWin))
  353.         ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
  354. #endif
  355.     if (qe)
  356.     {
  357.         qe->pScreen = sprite.hot.pScreen;
  358.         qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
  359.         qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
  360.     }
  361.     }
  362.     ROOT = WindowTable[sprite.hot.pScreen->myNum];
  363. }
  364.  
  365. static void
  366. ConfineCursorToWindow(pWin, generateEvents)
  367.     WindowPtr pWin;
  368.     Bool generateEvents;
  369. {
  370.     ScreenPtr pScreen = pWin->drawable.pScreen;
  371.  
  372.     if (syncEvents.playingEvents)
  373.     {
  374.     CheckVirtualMotion((QdEventPtr)NULL, pWin);
  375.     SyntheticMotion(sprite.hot.x, sprite.hot.y);
  376.     }
  377.     else
  378.     {
  379.     sprite.hotLimits = *(* pScreen->RegionExtents)(&pWin->borderSize);
  380. #ifdef SHAPE
  381.     sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize
  382.                            : NullRegion;
  383. #endif
  384.     CheckPhysLimits(sprite.current, generateEvents, pScreen);
  385.     (* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits);
  386.     }
  387. }
  388.  
  389. Bool
  390. PointerConfinedToScreen()
  391. {
  392.     register GrabPtr grab = inputInfo.pointer->grab;
  393.  
  394.     return (grab && grab->confineTo);
  395. }
  396.  
  397. static void
  398. ChangeToCursor(cursor)
  399.     CursorPtr cursor;
  400. {
  401.     if (cursor != sprite.current)
  402.     {
  403.     if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
  404.         (sprite.current->bits->yhot != cursor->bits->yhot))
  405.         CheckPhysLimits(cursor, FALSE, (ScreenPtr)NULL);
  406.     (*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
  407.                           cursor);
  408.     sprite.current = cursor;
  409.     }
  410. }
  411.  
  412. /* returns true if b is a descendent of a */
  413. Bool
  414. IsParent(a, b)
  415.     register WindowPtr a, b;
  416. {
  417.     for (b = b->parent; b; b = b->parent)
  418.     if (b == a) return TRUE;
  419.     return FALSE;
  420. }
  421.  
  422. static void
  423. PostNewCursor()
  424. {
  425.     register    WindowPtr win;
  426.     register    GrabPtr grab = inputInfo.pointer->grab;
  427.  
  428.     if (syncEvents.playingEvents)
  429.     return;
  430.     if (grab)
  431.     {
  432.     if (grab->cursor)
  433.     {
  434.         ChangeToCursor(grab->cursor);
  435.         return;
  436.     }
  437.     if (IsParent(grab->window, sprite.win))
  438.         win = sprite.win;
  439.     else
  440.         win = grab->window;
  441.     }
  442.     else
  443.     win = sprite.win;
  444.     for (; win; win = win->parent)
  445.     if (win->optional && win->optional->cursor != NullCursor)
  446.     {
  447.         ChangeToCursor(win->optional->cursor);
  448.         return;
  449.     }
  450. }
  451.  
  452. WindowPtr
  453. GetCurrentRootWindow()
  454. {
  455.     return ROOT;
  456. }
  457.  
  458. WindowPtr
  459. GetSpriteWindow()
  460. {
  461.     return sprite.win;
  462. }
  463.  
  464. #define NoticeTime(xE) { \
  465.     if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \
  466.     currentTime.months++; \
  467.     currentTime.milliseconds = (xE)->u.keyButtonPointer.time; }
  468.  
  469. void
  470. NoticeEventTime(xE)
  471.     register xEvent *xE;
  472. {
  473.     if (!syncEvents.playingEvents)
  474.     NoticeTime(xE);
  475. }
  476.  
  477. /**************************************************************************
  478.  *            The following procedures deal with synchronous events       *
  479.  **************************************************************************/
  480.  
  481. static void
  482. EnqueueEvent(xE, device, count)
  483.     xEvent        *xE;
  484.     DeviceIntPtr    device;
  485.     int            count;
  486. {
  487.     register QdEventPtr tail = *syncEvents.pendtail;
  488.     register QdEventPtr qe;
  489.     xEvent        *qxE;
  490.  
  491.     NoticeTime(xE)
  492.     if (xE->u.u.type == MotionNotify)
  493.     {
  494.     sprite.hotPhys.x = xE->u.keyButtonPointer.rootX;
  495.     sprite.hotPhys.y = xE->u.keyButtonPointer.rootY;
  496.     /* do motion compression */
  497.     if (tail &&
  498.         (tail->event->u.u.type == MotionNotify) &&
  499.         (tail->pScreen == sprite.hotPhys.pScreen))
  500.     {
  501.         tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
  502.         tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y;
  503.         return;
  504.     }
  505.     }
  506.     qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + (count * sizeof(xEvent)));
  507.     if (!qe)
  508.     return;
  509.     qe->next = (QdEventPtr)NULL;
  510.     qe->device = device;
  511.     qe->pScreen = sprite.hotPhys.pScreen;
  512.     qe->months = currentTime.months;
  513.     qe->event = (xEvent *)(qe + 1);
  514.     qe->evcount = count;
  515.     for (qxE = qe->event; --count >= 0; qxE++, xE++)
  516.     *qxE = *xE;
  517.     if (tail)
  518.     syncEvents.pendtail = &tail->next;
  519.     *syncEvents.pendtail = qe;
  520. }
  521.  
  522. static void
  523. PlayReleasedEvents()
  524. {
  525.     register QdEventPtr *prev, qe;
  526.  
  527.     prev = &syncEvents.pending;
  528.     while (qe = *prev)
  529.     {
  530.     if (!qe->device->sync.frozen)
  531.     {
  532.         *prev = qe->next;
  533.         if (*syncEvents.pendtail == *prev)
  534.         syncEvents.pendtail = prev;
  535.         if (qe->event->u.u.type == MotionNotify)
  536.         CheckVirtualMotion(qe, NullWindow);
  537.         syncEvents.time.months = qe->months;
  538.         syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
  539.         (*qe->device->public.processInputProc)(qe->event, qe->device,
  540.                            qe->evcount);
  541.         xfree(qe);
  542.         if (inputInfo.pointer->sync.frozen &&
  543.         inputInfo.keyboard->sync.frozen)
  544.         break;
  545.         /* Playing the event may have unfrozen another device. */
  546.         /* So to play it safe, restart at the head of the queue */
  547.         prev = &syncEvents.pending;
  548.     }
  549.     else
  550.         prev = &qe->next;
  551.     } 
  552. }
  553.  
  554. static void
  555. FreezeThaw(dev, frozen)
  556.     register DeviceIntPtr dev;
  557.     Bool frozen;
  558. {
  559.     dev->sync.frozen = frozen;
  560.     if (frozen)
  561.     dev->public.processInputProc = EnqueueEvent;
  562.     else
  563.     dev->public.processInputProc = dev->public.realInputProc;
  564. }
  565.  
  566. void
  567. ComputeFreezes()
  568. {
  569.     register DeviceIntPtr replayDev = syncEvents.replayDev;
  570.     register int i;
  571.     WindowPtr w;
  572.     register xEvent *xE;
  573.     int count;
  574.     GrabPtr grab;
  575.     register DeviceIntPtr dev;
  576.  
  577.     for (dev = inputInfo.devices; dev; dev = dev->next)
  578.     FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN));
  579.     if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
  580.     return;
  581.     syncEvents.playingEvents = TRUE;
  582.     if (replayDev)
  583.     {
  584.     xE = replayDev->sync.event;
  585.     count = replayDev->sync.evcount;
  586.     syncEvents.replayDev = (DeviceIntPtr)NULL;
  587.     w = XYToWindow(
  588.         xE->u.keyButtonPointer.rootX, xE->u.keyButtonPointer.rootY);
  589.     for (i = 0; i < spriteTraceGood; i++)
  590.         if (syncEvents.replayWin == spriteTrace[i])
  591.         {
  592.         if (!CheckDeviceGrabs(replayDev, xE, i+1, count))
  593.             if (replayDev->focus)
  594.             DeliverFocusedEvent(replayDev, xE, w, count);
  595.             else
  596.             DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
  597.                         replayDev, count);
  598.         goto playmore;
  599.         }
  600.     /* must not still be in the same stack */
  601.     if (replayDev->focus)
  602.         DeliverFocusedEvent(replayDev, xE, w, count);
  603.     else
  604.         DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
  605.     }
  606. playmore:
  607.     for (dev = inputInfo.devices; dev; dev = dev->next)
  608.     {
  609.     if (!dev->sync.frozen)
  610.     {
  611.         PlayReleasedEvents();
  612.         break;
  613.     }
  614.     }
  615.     syncEvents.playingEvents = FALSE;
  616.     /* the following may have been skipped during replay, so do it now */
  617.     if ((grab = inputInfo.pointer->grab) && grab->confineTo)
  618.     {
  619.     if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
  620.         sprite.hotPhys.x = sprite.hotPhys.y = 0;
  621.     ConfineCursorToWindow(grab->confineTo, TRUE);
  622.     }
  623.     else
  624.     ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
  625.                   TRUE);
  626.     PostNewCursor();
  627. }
  628.  
  629. void
  630. CheckGrabForSyncs(thisDev, thisMode, otherMode)
  631.     register DeviceIntPtr thisDev;
  632.     Bool thisMode, otherMode;
  633. {
  634.     register GrabPtr grab = thisDev->grab;
  635.     register DeviceIntPtr dev;
  636.  
  637.     if (thisMode == GrabModeSync)
  638.     thisDev->sync.state = FROZEN_NO_EVENT;
  639.     else
  640.     {    /* free both if same client owns both */
  641.     thisDev->sync.state = THAWED;
  642.     if (thisDev->sync.other &&
  643.         (CLIENT_BITS(thisDev->sync.other->resource) ==
  644.          CLIENT_BITS(grab->resource)))
  645.         thisDev->sync.other = NullGrab;
  646.     }
  647.     for (dev = inputInfo.devices; dev; dev = dev->next)
  648.     {
  649.     if (dev != thisDev)
  650.     {
  651.         if (otherMode == GrabModeSync)
  652.         dev->sync.other = grab;
  653.         else
  654.         {    /* free both if same client owns both */
  655.         if (dev->sync.other &&
  656.             (CLIENT_BITS(dev->sync.other->resource) ==
  657.              CLIENT_BITS(grab->resource)))
  658.             dev->sync.other = NullGrab;
  659.         }
  660.     }
  661.     }
  662.     ComputeFreezes();
  663. }
  664.  
  665. void
  666. ActivatePointerGrab(mouse, grab, time, autoGrab)
  667.     register GrabPtr grab;
  668.     register DeviceIntPtr mouse;
  669.     TimeStamp time;
  670.     Bool autoGrab;
  671. {
  672.     WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
  673.                      : sprite.win;
  674.  
  675.     if (grab->confineTo)
  676.     {
  677.     if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
  678.         sprite.hotPhys.x = sprite.hotPhys.y = 0;
  679.     ConfineCursorToWindow(grab->confineTo, FALSE);
  680.     }
  681.     DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
  682.     mouse->valuator->motionHintWindow = NullWindow;
  683.     if (syncEvents.playingEvents)
  684.     mouse->grabTime = syncEvents.time;
  685.     else
  686.     mouse->grabTime = time;
  687.     if (grab->cursor)
  688.     grab->cursor->refcnt++;
  689.     mouse->activeGrab = *grab;
  690.     mouse->grab = &mouse->activeGrab;
  691.     mouse->fromPassiveGrab = autoGrab;
  692.     PostNewCursor();
  693.     CheckGrabForSyncs(mouse,
  694.               (Bool)grab->pointerMode, (Bool)grab->keyboardMode);
  695. }
  696.  
  697. void
  698. DeactivatePointerGrab(mouse)
  699.     register DeviceIntPtr mouse;
  700. {
  701.     register GrabPtr grab = mouse->grab;
  702.     register DeviceIntPtr dev;
  703.  
  704.     mouse->valuator->motionHintWindow = NullWindow;
  705.     mouse->grab = NullGrab;
  706.     mouse->sync.state = NOT_GRABBED;
  707.     mouse->fromPassiveGrab = FALSE;
  708.     for (dev = inputInfo.devices; dev; dev = dev->next)
  709.     {
  710.     if (dev->sync.other == grab)
  711.         dev->sync.other = NullGrab;
  712.     }
  713.     DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
  714.     if (grab->confineTo)
  715.     ConfineCursorToWindow(ROOT, FALSE);
  716.     PostNewCursor();
  717.     if (grab->cursor)
  718.     FreeCursor(grab->cursor, (Cursor)0);
  719.     ComputeFreezes();
  720. }
  721.  
  722. void
  723. ActivateKeyboardGrab(keybd, grab, time, passive)
  724.     GrabPtr grab;
  725.     register DeviceIntPtr keybd;
  726.     TimeStamp time;
  727.     Bool passive;
  728. {
  729.     WindowPtr oldWin = (keybd->grab) ? keybd->grab->window
  730.                      : keybd->focus->win;
  731.  
  732.     if (oldWin == FollowKeyboardWin)
  733.     oldWin = inputInfo.keyboard->focus->win;
  734.     if (keybd->valuator)
  735.     keybd->valuator->motionHintWindow = NullWindow;
  736.     DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);
  737.     if (syncEvents.playingEvents)
  738.     keybd->grabTime = syncEvents.time;
  739.     else
  740.     keybd->grabTime = time;
  741.     keybd->activeGrab = *grab;
  742.     keybd->grab = &keybd->activeGrab;
  743.     keybd->fromPassiveGrab = passive;
  744.     CheckGrabForSyncs(keybd,
  745.               (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
  746. }
  747.  
  748. void
  749. DeactivateKeyboardGrab(keybd)
  750.     register DeviceIntPtr keybd;
  751. {
  752.     register GrabPtr grab = keybd->grab;
  753.     register DeviceIntPtr dev;
  754.     register WindowPtr focusWin = keybd->focus->win;
  755.  
  756.     if (focusWin == FollowKeyboardWin)
  757.     focusWin = inputInfo.keyboard->focus->win;
  758.     if (keybd->valuator)
  759.     keybd->valuator->motionHintWindow = NullWindow;
  760.     keybd->grab = NullGrab;
  761.     keybd->sync.state = NOT_GRABBED;
  762.     keybd->fromPassiveGrab = FALSE;
  763.     for (dev = inputInfo.devices; dev; dev = dev->next)
  764.     {
  765.     if (dev->sync.other == grab)
  766.         dev->sync.other = NullGrab;
  767.     }
  768.     DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
  769.     ComputeFreezes();
  770. }
  771.  
  772. void
  773. AllowSome(client, time, thisDev, newState)
  774.     ClientPtr        client;
  775.     TimeStamp        time;
  776.     register DeviceIntPtr thisDev;
  777.     int            newState;
  778. {
  779.     Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
  780.     TimeStamp grabTime;
  781.     register DeviceIntPtr dev;
  782.  
  783.     thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
  784.     thisSynced = FALSE;
  785.     otherGrabbed = FALSE;
  786.     othersFrozen = TRUE;
  787.     grabTime = thisDev->grabTime;
  788.     for (dev = inputInfo.devices; dev; dev = dev->next)
  789.     {
  790.     if (dev == thisDev)
  791.         continue;
  792.     if (dev->grab && SameClient(dev->grab, client))
  793.     {
  794.         if (!(thisGrabbed || otherGrabbed) ||
  795.         (CompareTimeStamps(dev->grabTime, grabTime) == LATER))
  796.         grabTime = dev->grabTime;
  797.         otherGrabbed = TRUE;
  798.         if (thisDev->sync.other == dev->grab)
  799.         thisSynced = TRUE;
  800.         if (dev->sync.state < FROZEN)
  801.         othersFrozen = FALSE;
  802.     }
  803.     else if (!thisGrabbed || (dev->sync.other != thisDev->grab))
  804.         othersFrozen = FALSE;
  805.     }
  806.     if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
  807.     return;
  808.     if ((CompareTimeStamps(time, currentTime) == LATER) ||
  809.     (CompareTimeStamps(time, grabTime) == EARLIER))
  810.     return;
  811.     switch (newState)
  812.     {
  813.     case THAWED:                /* Async */
  814.         if (thisGrabbed)
  815.         thisDev->sync.state = THAWED;
  816.         if (thisSynced)
  817.         thisDev->sync.other = NullGrab;
  818.         ComputeFreezes();
  819.         break;
  820.     case FREEZE_NEXT_EVENT:        /* Sync */
  821.         if (thisGrabbed)
  822.         {
  823.         thisDev->sync.state = FREEZE_NEXT_EVENT;
  824.         if (thisSynced)
  825.             thisDev->sync.other = NullGrab;
  826.         ComputeFreezes();
  827.         }
  828.         break;
  829.     case THAWED_BOTH:        /* AsyncBoth */
  830.         if (othersFrozen)
  831.         {
  832.         for (dev = inputInfo.devices; dev; dev = dev->next)
  833.         {
  834.             if (dev->grab && SameClient(dev->grab, client))
  835.             dev->sync.state = THAWED;
  836.             else
  837.             dev->sync.other = NullGrab;
  838.         }
  839.         ComputeFreezes();
  840.         }
  841.         break;
  842.     case FREEZE_BOTH_NEXT_EVENT:    /* SyncBoth */
  843.         if (othersFrozen)
  844.         {
  845.         for (dev = inputInfo.devices; dev; dev = dev->next)
  846.         {
  847.             if (dev->grab && SameClient(dev->grab, client))
  848.             dev->sync.state = FREEZE_BOTH_NEXT_EVENT;
  849.             else
  850.             dev->sync.other = NullGrab;
  851.         }
  852.         ComputeFreezes();
  853.         }
  854.         break;
  855.     case NOT_GRABBED:        /* Replay */
  856.         if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT)
  857.         {
  858.         syncEvents.replayDev = thisDev;
  859.         syncEvents.replayWin = thisDev->grab->window;
  860.         (*thisDev->DeactivateGrab)(thisDev);
  861.         syncEvents.replayDev = (DeviceIntPtr)NULL;
  862.         }
  863.         break;
  864.     case THAW_OTHERS:        /* AsyncOthers */
  865.         if (othersFrozen)
  866.         {
  867.         for (dev = inputInfo.devices; dev; dev = dev->next)
  868.         {
  869.             if (dev == thisDev)
  870.             continue;
  871.             if (dev->grab && SameClient(dev->grab, client))
  872.             dev->sync.state = THAWED;
  873.             else
  874.             dev->sync.other = NullGrab;
  875.         }
  876.         ComputeFreezes();
  877.         }
  878.         break;
  879.     }
  880. }
  881.  
  882. int
  883. ProcAllowEvents(client)
  884.     register ClientPtr client;
  885. {
  886.     TimeStamp        time;
  887.     DeviceIntPtr    mouse = inputInfo.pointer;
  888.     DeviceIntPtr    keybd = inputInfo.keyboard;
  889.     REQUEST(xAllowEventsReq);
  890.  
  891.     REQUEST_SIZE_MATCH(xAllowEventsReq);
  892.     time = ClientTimeToServerTime(stuff->time);
  893.     switch (stuff->mode)
  894.     {
  895.     case ReplayPointer:
  896.         AllowSome(client, time, mouse, NOT_GRABBED);
  897.         break;
  898.     case SyncPointer: 
  899.         AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
  900.         break;
  901.     case AsyncPointer: 
  902.         AllowSome(client, time, mouse, THAWED);
  903.         break;
  904.     case ReplayKeyboard: 
  905.         AllowSome(client, time, keybd, NOT_GRABBED);
  906.         break;
  907.     case SyncKeyboard: 
  908.         AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
  909.         break;
  910.     case AsyncKeyboard: 
  911.         AllowSome(client, time, keybd, THAWED);
  912.         break;
  913.     case SyncBoth:
  914.         AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
  915.         break;
  916.     case AsyncBoth:
  917.         AllowSome(client, time, keybd, THAWED_BOTH);
  918.         break;
  919.     default: 
  920.         client->errorValue = stuff->mode;
  921.         return BadValue;
  922.     }
  923.     return Success;
  924. }
  925.  
  926. void
  927. ReleaseActiveGrabs(client)
  928.     ClientPtr client;
  929. {
  930.     register DeviceIntPtr dev;
  931.  
  932.     for (dev = inputInfo.devices; dev; dev = dev->next)
  933.     {
  934.     if (dev->grab && SameClient(dev->grab, client))
  935.         (*dev->DeactivateGrab)(dev);
  936.     }
  937. }
  938.  
  939. /**************************************************************************
  940.  *            The following procedures deal with delivering events        *
  941.  **************************************************************************/
  942.  
  943. int
  944. TryClientEvents (client, pEvents, count, mask, filter, grab)
  945.     ClientPtr client;
  946.     GrabPtr grab;
  947.     xEvent *pEvents;
  948.     int count;
  949.     Mask mask, filter;
  950. {
  951.     int i;
  952.     int type;
  953.  
  954. #ifdef DEBUG
  955.     if (debug_events) ErrorF(
  956.     "Event([%d, %d], mask=0x%x), client=%d",
  957.     pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
  958. #endif
  959.     if ((client) && (client != serverClient) && (!client->clientGone) &&
  960.     ((filter == CantBeFiltered) || (mask & filter)))
  961.     {
  962.     if (grab && !SameClient(grab, client))
  963.         return -1; /* don't send, but notify caller */
  964.     type = pEvents->u.u.type;
  965.     if (type == MotionNotify)
  966.     {
  967.         if (mask & PointerMotionHintMask)
  968.         {
  969.         if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
  970.             pEvents->u.keyButtonPointer.event)
  971.         {
  972. #ifdef DEBUG
  973.             if (debug_events) ErrorF("\n");
  974. #endif
  975.             return 1; /* don't send, but pretend we did */
  976.         }
  977.         pEvents->u.u.detail = NotifyHint;
  978.         }
  979.         else
  980.         {
  981.         pEvents->u.u.detail = NotifyNormal;
  982.         }
  983.     }
  984. #ifdef XINPUT
  985.     else
  986.     {
  987.         extern int DeviceMotionNotify;
  988.  
  989.         if ((type == DeviceMotionNotify) &&
  990.         MaybeSendDeviceMotionNotifyHint (pEvents, mask) != 0)
  991.         return 1;
  992.     }
  993. #endif
  994.     type &= 0177;
  995.     if (type != KeymapNotify)
  996.     {
  997.         /* all extension events must have a sequence number */
  998.         for (i = 0; i < count; i++)
  999.         pEvents[i].u.u.sequenceNumber = client->sequence;
  1000.     }
  1001.  
  1002.     if (BitIsOn(criticalEvents, type))
  1003.         SetCriticalOutputPending();
  1004.  
  1005.     WriteEventsToClient(client, count, pEvents);
  1006. #ifdef DEBUG
  1007.     if (debug_events) ErrorF(  " delivered\n");
  1008. #endif
  1009.     return 1;
  1010.     }
  1011.     else
  1012.     {
  1013. #ifdef DEBUG
  1014.     if (debug_events) ErrorF("\n");
  1015. #endif
  1016.     return 0;
  1017.     }
  1018. }
  1019.  
  1020. int
  1021. DeliverEventsToWindow(pWin, pEvents, count, filter, grab, mskidx)
  1022.     register WindowPtr pWin;
  1023.     GrabPtr grab;
  1024.     xEvent *pEvents;
  1025.     int count;
  1026.     Mask filter;
  1027.     int mskidx;
  1028. {
  1029.     int deliveries = 0, nondeliveries = 0;
  1030.     int attempt;
  1031.     register InputClients *other;
  1032.     ClientPtr client = NullClient;
  1033.     Mask deliveryMask;     /* If a grab occurs due to a button press, then
  1034.                       this mask is the mask of the grab. */
  1035.     int type = pEvents->u.u.type;
  1036.  
  1037.     /* CantBeFiltered means only window owner gets the event */
  1038.     if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
  1039.     {
  1040.     /* if nobody ever wants to see this event, skip some work */
  1041.     if (filter != CantBeFiltered &&
  1042.         !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
  1043.         return 0;
  1044.     if (attempt = TryClientEvents(wClient(pWin), pEvents, count,
  1045.                       pWin->eventMask, filter, grab))
  1046.     {
  1047.         if (attempt > 0)
  1048.         {
  1049.         deliveries++;
  1050.         client = wClient(pWin);
  1051.         deliveryMask = pWin->eventMask;
  1052.         } else
  1053.         nondeliveries--;
  1054.     }
  1055.     }
  1056.     if (filter != CantBeFiltered)
  1057.     {
  1058.     if (type & EXTENSION_EVENT_BASE)
  1059.     {
  1060.         OtherInputMasks *inputMasks;
  1061.  
  1062.         inputMasks = wOtherInputMasks(pWin);
  1063.         if (!inputMasks ||
  1064.         !(inputMasks->inputEvents[mskidx] & filter))
  1065.         return 0;
  1066.         other = inputMasks->inputClients;
  1067.     }
  1068.     else
  1069.         other = (InputClients *)wOtherClients(pWin);
  1070.     for (; other; other = other->next)
  1071.     {
  1072.         if (attempt = TryClientEvents(rClient(other), pEvents, count,
  1073.                       other->mask[mskidx], filter, grab))
  1074.         {
  1075.         if (attempt > 0)
  1076.         {
  1077.             deliveries++;
  1078.             client = rClient(other);
  1079.             deliveryMask = other->mask[mskidx];
  1080.         } else
  1081.             nondeliveries--;
  1082.         }
  1083.     }
  1084.     }
  1085.     if ((type == ButtonPress) && deliveries && (!grab))
  1086.     {
  1087.     GrabRec tempGrab;
  1088.  
  1089.     tempGrab.device = inputInfo.pointer;
  1090.     tempGrab.resource = client->clientAsMask;
  1091.     tempGrab.window = pWin;
  1092.     tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
  1093.     tempGrab.eventMask = deliveryMask;
  1094.     tempGrab.keyboardMode = GrabModeAsync;
  1095.     tempGrab.pointerMode = GrabModeAsync;
  1096.     tempGrab.confineTo = NullWindow;
  1097.     tempGrab.cursor = NullCursor;
  1098.     (*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
  1099.                        currentTime, TRUE);
  1100.     }
  1101.     else if ((type == MotionNotify) && deliveries)
  1102.     inputInfo.pointer->valuator->motionHintWindow = pWin;
  1103. #ifdef XINPUT
  1104.     else
  1105.     {
  1106.     extern int DeviceMotionNotify, DeviceButtonPress;
  1107.  
  1108.     if (((type == DeviceMotionNotify) || (type == DeviceButtonPress)) &&
  1109.         deliveries)
  1110.         CheckDeviceGrabAndHintWindow (pWin, type, pEvents, grab, client, 
  1111.                       deliveryMask);
  1112.     }
  1113. #endif
  1114.     if (deliveries)
  1115.     return deliveries;
  1116.     return nondeliveries;
  1117. }
  1118.  
  1119. /* If the event goes to dontClient, don't send it and return 0.  if
  1120.    send works,  return 1 or if send didn't work, return 2.
  1121.    Only works for core events.
  1122. */
  1123.  
  1124. int
  1125. MaybeDeliverEventsToClient(pWin, pEvents, count, filter, dontClient)
  1126.     register WindowPtr pWin;
  1127.     xEvent *pEvents;
  1128.     int count;
  1129.     Mask filter;
  1130.     ClientPtr dontClient;
  1131. {
  1132.     register OtherClients *other;
  1133.  
  1134.     if (pWin->eventMask & filter)
  1135.     {
  1136.         if (wClient(pWin) == dontClient)
  1137.         return 0;
  1138.     return TryClientEvents(wClient(pWin), pEvents, count,
  1139.                    pWin->eventMask, filter, NullGrab);
  1140.     }
  1141.     for (other = wOtherClients(pWin); other; other = other->next)
  1142.     {
  1143.     if (other->mask & filter)
  1144.     {
  1145.             if (SameClient(other, dontClient))
  1146.         return 0;
  1147.         return TryClientEvents(rClient(other), pEvents, count,
  1148.                    other->mask, filter, NullGrab);
  1149.     }
  1150.     }
  1151.     return 2;
  1152. }
  1153.  
  1154. static void
  1155. FixUpEventFromWindow(xE, pWin, child, calcChild)
  1156.     xEvent *xE;
  1157.     WindowPtr pWin;
  1158.     Window child;
  1159.     Bool calcChild;
  1160. {
  1161.     if (calcChild)
  1162.     {
  1163.         WindowPtr w=spriteTrace[spriteTraceGood-1];
  1164.  
  1165.     /* If the search ends up past the root should the child field be 
  1166.          set to none or should the value in the argument be passed 
  1167.         through. It probably doesn't matter since everyone calls 
  1168.         this function with child == None anyway. */
  1169.  
  1170.         while (w) 
  1171.         {
  1172.             /* If the source window is same as event window, child should be
  1173.         none.  Don't bother going all all the way back to the root. */
  1174.  
  1175.          if (w == pWin)
  1176.         { 
  1177.            child = None;
  1178.          break;
  1179.         }
  1180.         
  1181.         if (w->parent == pWin)
  1182.         {
  1183.         child = w->drawable.id;
  1184.         break;
  1185.             }
  1186.          w = w->parent;
  1187.         }         
  1188.     }
  1189.     xE->u.keyButtonPointer.root = ROOT->drawable.id;
  1190.     xE->u.keyButtonPointer.event = pWin->drawable.id;
  1191.     if (sprite.hot.pScreen == pWin->drawable.pScreen)
  1192.     {
  1193.     xE->u.keyButtonPointer.sameScreen = xTrue;
  1194.     xE->u.keyButtonPointer.child = child;
  1195.     xE->u.keyButtonPointer.eventX =
  1196.         xE->u.keyButtonPointer.rootX - pWin->drawable.x;
  1197.     xE->u.keyButtonPointer.eventY =
  1198.         xE->u.keyButtonPointer.rootY - pWin->drawable.y;
  1199.     }
  1200.     else
  1201.     {
  1202.     xE->u.keyButtonPointer.sameScreen = xFalse;
  1203.     xE->u.keyButtonPointer.child = None;
  1204.     xE->u.keyButtonPointer.eventX = 0;
  1205.     xE->u.keyButtonPointer.eventY = 0;
  1206.     }
  1207. }
  1208.  
  1209. int
  1210. DeliverDeviceEvents(pWin, xE, grab, stopAt, dev, count)
  1211.     register WindowPtr pWin, stopAt;
  1212.     register xEvent *xE;
  1213.     GrabPtr grab;
  1214.     DeviceIntPtr dev;
  1215.     int count;
  1216. {
  1217.     Window child = None;
  1218.     int type = xE->u.u.type;
  1219.     Mask filter = filters[type];
  1220.     int deliveries = 0;
  1221.  
  1222.     if (type & EXTENSION_EVENT_BASE)
  1223.     {
  1224.     register OtherInputMasks *inputMasks;
  1225.     int mskidx = dev->id;
  1226.  
  1227.     inputMasks = wOtherInputMasks(pWin);
  1228.     if (!inputMasks || !(filter & inputMasks->deliverableEvents[mskidx]))
  1229.         return 0;
  1230.     while (pWin && inputMasks)
  1231.     {
  1232.         if (inputMasks->inputEvents[mskidx] & filter)
  1233.         {
  1234.         FixUpEventFromWindow(xE, pWin, child, FALSE);
  1235.         deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
  1236.                            grab, mskidx);
  1237.         if (deliveries > 0)
  1238.             return deliveries;
  1239.         }
  1240.         if ((deliveries < 0) ||
  1241.         (pWin == stopAt) ||
  1242.         (filter & inputMasks->dontPropagateMask[mskidx]))
  1243.         return 0;
  1244.         child = pWin->drawable.id;
  1245.         pWin = pWin->parent;
  1246.         inputMasks = wOtherInputMasks(pWin);
  1247.     }
  1248.     }
  1249.     else
  1250.     {
  1251.     if (!(filter & pWin->deliverableEvents))
  1252.         return 0;
  1253.     while (pWin)
  1254.     {
  1255.         if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
  1256.         {
  1257.         FixUpEventFromWindow(xE, pWin, child, FALSE);
  1258.         deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
  1259.                            grab, 0);
  1260.         if (deliveries > 0)
  1261.             return deliveries;
  1262.         }
  1263.         if ((deliveries < 0) ||
  1264.         (pWin == stopAt) ||
  1265.         (filter & wDontPropagateMask(pWin)))
  1266.         return 0;
  1267.         child = pWin->drawable.id;
  1268.         pWin = pWin->parent;
  1269.     }
  1270.     }
  1271.     return 0;
  1272. }
  1273.  
  1274. /* not useful for events that propagate up the tree or extension events */
  1275. int
  1276. DeliverEvents(pWin, xE, count, otherParent)
  1277.     register WindowPtr pWin, otherParent;
  1278.     register xEvent *xE;
  1279.     int count;
  1280. {
  1281.     Mask filter;
  1282.     int     deliveries;
  1283.  
  1284.     if (!count)
  1285.     return 0;
  1286.     filter = filters[xE->u.u.type];
  1287.     if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
  1288.     xE->u.destroyNotify.event = pWin->drawable.id;
  1289.     if (filter != StructureAndSubMask)
  1290.     return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0);
  1291.     deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask,
  1292.                        NullGrab, 0);
  1293.     if (pWin->parent)
  1294.     {
  1295.     xE->u.destroyNotify.event = pWin->parent->drawable.id;
  1296.     deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
  1297.                         SubstructureNotifyMask, NullGrab,
  1298.                         0);
  1299.     if (xE->u.u.type == ReparentNotify)
  1300.     {
  1301.         xE->u.destroyNotify.event = otherParent->drawable.id;
  1302.         deliveries += DeliverEventsToWindow(otherParent, xE, count,
  1303.                         SubstructureNotifyMask,
  1304.                         NullGrab, 0);
  1305.     }
  1306.     }
  1307.     return deliveries;
  1308. }
  1309.  
  1310. static WindowPtr 
  1311. XYToWindow(x, y)
  1312.     int x, y;
  1313. {
  1314.     register WindowPtr  pWin;
  1315. #ifdef SHAPE
  1316.     BoxRec        box;
  1317. #endif
  1318.  
  1319.     spriteTraceGood = 1;    /* root window still there */
  1320.     pWin = ROOT->firstChild;
  1321.     while (pWin)
  1322.     {
  1323.     if ((pWin->mapped) &&
  1324.         (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
  1325.         (x < pWin->drawable.x + (int)pWin->drawable.width +
  1326.             wBorderWidth(pWin)) &&
  1327.         (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
  1328.         (y < pWin->drawable.y + (int)pWin->drawable.height +
  1329.             wBorderWidth (pWin))
  1330. #ifdef SHAPE
  1331.         /* When a window is shaped, a further check
  1332.          * is made to see if the point is inside
  1333.          * borderSize
  1334.          */
  1335.         && (!wBoundingShape(pWin) ||
  1336.             (*pWin->drawable.pScreen->PointInRegion)
  1337.                 (&pWin->borderSize, x, y, &box))
  1338. #endif
  1339.         )
  1340.     {
  1341.         if (spriteTraceGood >= spriteTraceSize)
  1342.         {
  1343.         spriteTraceSize += 10;
  1344.         spriteTrace = (WindowPtr *)xrealloc(
  1345.             spriteTrace, spriteTraceSize*sizeof(WindowPtr));
  1346.         if (!spriteTrace)
  1347.             FatalError("could not realloc spriteTrace"); /* XXX */
  1348.         }
  1349.         spriteTrace[spriteTraceGood++] = pWin;
  1350.         pWin = pWin->firstChild;
  1351.     }
  1352.     else
  1353.         pWin = pWin->nextSib;
  1354.     }
  1355.     return spriteTrace[spriteTraceGood-1];
  1356. }
  1357.  
  1358. static Bool
  1359. CheckMotion(xE)
  1360.     xEvent *xE;
  1361. {
  1362.     WindowPtr prevSpriteWin = sprite.win;
  1363.  
  1364.     if (xE && !syncEvents.playingEvents)
  1365.     {
  1366.     if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
  1367.     {
  1368.         sprite.hot.pScreen = sprite.hotPhys.pScreen;
  1369.         ROOT = WindowTable[sprite.hot.pScreen->myNum];
  1370.     }
  1371.     sprite.hot.x = xE->u.keyButtonPointer.rootX;
  1372.     sprite.hot.y = xE->u.keyButtonPointer.rootY;
  1373.     if (sprite.hot.x < sprite.physLimits.x1)
  1374.         sprite.hot.x = sprite.physLimits.x1;
  1375.     else if (sprite.hot.x >= sprite.physLimits.x2)
  1376.         sprite.hot.x = sprite.physLimits.x2 - 1;
  1377.     if (sprite.hot.y < sprite.physLimits.y1)
  1378.         sprite.hot.y = sprite.physLimits.y1;
  1379.     else if (sprite.hot.y >= sprite.physLimits.y2)
  1380.         sprite.hot.y = sprite.physLimits.y2 - 1;
  1381. #ifdef SHAPE
  1382.     if (sprite.hotShape)
  1383.         ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
  1384. #endif
  1385.     sprite.hotPhys = sprite.hot;
  1386.     if ((sprite.hotPhys.x != xE->u.keyButtonPointer.rootX) ||
  1387.         (sprite.hotPhys.y != xE->u.keyButtonPointer.rootY))
  1388.         (*sprite.hotPhys.pScreen->SetCursorPosition)(
  1389.         sprite.hotPhys.pScreen,
  1390.         sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
  1391.     xE->u.keyButtonPointer.rootX = sprite.hot.x;
  1392.     xE->u.keyButtonPointer.rootY = sprite.hot.y;
  1393.     }
  1394.  
  1395.     sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
  1396. #ifdef notyet
  1397.     if (!(sprite.win->deliverableEvents &
  1398.       Motion_Filter(inputInfo.pointer->button))
  1399.     !syncEvents.playingEvents)
  1400.     {
  1401.     /* XXX Do PointerNonInterestBox here */
  1402.     }
  1403. #endif
  1404.     if (sprite.win != prevSpriteWin)
  1405.     {
  1406.     if (prevSpriteWin != NullWindow) {
  1407.         if (!xE)
  1408.         UpdateCurrentTimeIf();
  1409.         DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
  1410.     }
  1411.     PostNewCursor();
  1412.         return FALSE;
  1413.     }
  1414.     return TRUE;
  1415. }
  1416.  
  1417. WindowsRestructured()
  1418. {
  1419.     (void) CheckMotion((xEvent *)NULL);
  1420. }
  1421.  
  1422. void
  1423. DefineInitialRootWindow(win)
  1424.     register WindowPtr win;
  1425. {
  1426.     register ScreenPtr pScreen = win->drawable.pScreen;
  1427.  
  1428.     sprite.hotPhys.pScreen = pScreen;
  1429.     sprite.hotPhys.x = pScreen->width / 2;
  1430.     sprite.hotPhys.y = pScreen->height / 2;
  1431.     sprite.hot = sprite.hotPhys;
  1432.     sprite.hotLimits.x2 = pScreen->width;
  1433.     sprite.hotLimits.y2 = pScreen->height;
  1434.     sprite.win = win;
  1435.     sprite.current = wCursor (win);
  1436.     spriteTraceGood = 1;
  1437.     ROOT = win;
  1438.     (*pScreen->CursorLimits) (
  1439.     pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits);
  1440.     (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
  1441.     (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE);
  1442.     (*pScreen->DisplayCursor) (pScreen, sprite.current);
  1443. }
  1444.  
  1445. /*
  1446.  * This does not take any shortcuts, and even ignores its argument, since
  1447.  * it does not happen very often, and one has to walk up the tree since
  1448.  * this might be a newly instantiated cursor for an intermediate window
  1449.  * between the one the pointer is in and the one that the last cursor was
  1450.  * instantiated from.
  1451.  */
  1452. /*ARGSUSED*/
  1453. void
  1454. WindowHasNewCursor(pWin)
  1455.     WindowPtr pWin;
  1456. {
  1457.     PostNewCursor();
  1458. }
  1459.  
  1460. void
  1461. NewCurrentScreen(newScreen, x, y)
  1462.     ScreenPtr newScreen;
  1463.     int x,y;
  1464. {
  1465.     sprite.hotPhys.x = x;
  1466.     sprite.hotPhys.y = y;
  1467.     if (newScreen != sprite.hotPhys.pScreen)
  1468.     ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE);
  1469. }
  1470.  
  1471. int
  1472. ProcWarpPointer(client)
  1473.     ClientPtr client;
  1474. {
  1475.     WindowPtr    dest = NULL;
  1476.     int        x, y;
  1477.     ScreenPtr    newScreen;
  1478.  
  1479.     REQUEST(xWarpPointerReq);
  1480.  
  1481.     REQUEST_SIZE_MATCH(xWarpPointerReq);
  1482.     if (stuff->dstWid != None)
  1483.     {
  1484.     dest = LookupWindow(stuff->dstWid, client);
  1485.     if (!dest)
  1486.         return BadWindow;
  1487.     }
  1488.     x = sprite.hotPhys.x;
  1489.     y = sprite.hotPhys.y;
  1490.     if (stuff->srcWid != None)
  1491.     {
  1492.     int     winX, winY;
  1493.         WindowPtr source = LookupWindow(stuff->srcWid, client);
  1494.     if (!source)
  1495.         return BadWindow;
  1496.     winX = source->drawable.x;
  1497.     winY = source->drawable.y;
  1498.     if ((x < (winX + stuff->srcX)) ||
  1499.         (y < (winY + stuff->srcY)) ||
  1500.         ((stuff->srcWidth != 0) &&
  1501.          (winX + stuff->srcX + (int)stuff->srcWidth < x)) ||
  1502.         ((stuff->srcHeight != 0) &&
  1503.          (winY + stuff->srcY + (int)stuff->srcHeight < y)) ||
  1504.         (!PointInWindowIsVisible(source, x, y)))
  1505.         return Success;
  1506.     }
  1507.     if (dest)
  1508.     {
  1509.     x = dest->drawable.x;
  1510.     y = dest->drawable.y;
  1511.     newScreen = dest->drawable.pScreen;
  1512.     }
  1513.     else
  1514.     newScreen = sprite.hotPhys.pScreen;
  1515.     x += stuff->dstX;
  1516.     y += stuff->dstY;
  1517.     if (x < 0)
  1518.     x = 0;
  1519.     else if (x >= newScreen->width)
  1520.     x = newScreen->width - 1;
  1521.     if (y < 0)
  1522.     y = 0;
  1523.     else if (y >= newScreen->height)
  1524.     y = newScreen->height - 1;
  1525.  
  1526.     if (newScreen == sprite.hotPhys.pScreen)
  1527.     {
  1528.     if (x < sprite.physLimits.x1)
  1529.         x = sprite.physLimits.x1;
  1530.     else if (x >= sprite.physLimits.x2)
  1531.         x = sprite.physLimits.x2 - 1;
  1532.     if (y < sprite.physLimits.y1)
  1533.         y = sprite.physLimits.y1;
  1534.     else if (y >= sprite.physLimits.y2)
  1535.         y = sprite.physLimits.y2 - 1;
  1536. #ifdef SHAPE
  1537.     if (sprite.hotShape)
  1538.         ConfineToShape(sprite.hotShape, &x, &y);
  1539. #endif
  1540.     (*newScreen->SetCursorPosition)(newScreen, x, y, TRUE);
  1541.     }
  1542.     else if (!PointerConfinedToScreen())
  1543.     {
  1544.     NewCurrentScreen(newScreen, x, y);
  1545.     }
  1546.     return Success;
  1547. }
  1548.  
  1549. /* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
  1550.     passive grab set on the window to be activated. */
  1551.  
  1552. static Bool
  1553. CheckPassiveGrabsOnWindow(pWin, device, xE, count)
  1554.     WindowPtr pWin;
  1555.     register DeviceIntPtr device;
  1556.     register xEvent *xE;
  1557.     int count;
  1558. {
  1559.     register GrabPtr grab = wPassiveGrabs(pWin);
  1560.     GrabRec tempGrab;
  1561.     register xEvent *dxE;
  1562.  
  1563.     if (!grab)
  1564.     return FALSE;
  1565.     tempGrab.window = pWin;
  1566.     tempGrab.device = device;
  1567.     tempGrab.type = xE->u.u.type;
  1568.     tempGrab.detail.exact = xE->u.u.detail;
  1569.     tempGrab.detail.pMask = NULL;
  1570.     tempGrab.modifiersDetail.pMask = NULL;
  1571.     for (; grab; grab = grab->next)
  1572.     {
  1573.     tempGrab.modifierDevice = grab->modifierDevice;
  1574.     tempGrab.modifiersDetail.exact = grab->modifierDevice->key->state;
  1575.     if (GrabMatchesSecond(&tempGrab, grab))
  1576.     {
  1577.         (*device->ActivateGrab)(device, grab, currentTime, TRUE);
  1578.  
  1579.         FixUpEventFromWindow(xE, grab->window, None, TRUE);
  1580.  
  1581.         (void) TryClientEvents(rClient(grab), xE, count,
  1582.                    filters[xE->u.u.type],
  1583.                    filters[xE->u.u.type],  grab);
  1584.  
  1585.         if (device->sync.state == FROZEN_NO_EVENT)
  1586.         {
  1587.             device->sync.event = (xEvent *)xrealloc(device->sync.event,
  1588.                             count*sizeof(xEvent));
  1589.         device->sync.evcount = count;
  1590.         for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
  1591.             *dxE = *xE;
  1592.             device->sync.state = FROZEN_WITH_EVENT;
  1593.             }    
  1594.         return TRUE;
  1595.     }
  1596.     }
  1597.     return FALSE;
  1598. }
  1599.  
  1600. /*
  1601. "CheckDeviceGrabs" handles both keyboard and pointer events that may cause
  1602. a passive grab to be activated.  If the event is a keyboard event, the
  1603. ancestors of the focus window are traced down and tried to see if they have
  1604. any passive grabs to be activated.  If the focus window itself is reached and
  1605. it's descendants contain they pointer, the ancestors of the window that the
  1606. pointer is in are then traced down starting at the focus window, otherwise no
  1607. grabs are activated.  If the event is a pointer event, the ancestors of the
  1608. window that the pointer is in are traced down starting at the root until
  1609. CheckPassiveGrabs causes a passive grab to activate or all the windows are
  1610. tried. PRH
  1611. */
  1612.  
  1613. Bool
  1614. CheckDeviceGrabs(device, xE, checkFirst, count)
  1615.     register DeviceIntPtr device;
  1616.     register xEvent *xE;
  1617.     int checkFirst;
  1618.     int count;
  1619. {
  1620.     register int i;
  1621.     register WindowPtr pWin;
  1622.     register FocusClassPtr focus = device->focus;
  1623.  
  1624.     i = checkFirst;
  1625.  
  1626.     if (focus)
  1627.     {
  1628.     for (; i < focus->traceGood; i++)
  1629.     {
  1630.         pWin = focus->trace[i];
  1631.         if (pWin->optional &&
  1632.         CheckPassiveGrabsOnWindow(pWin, device, xE, count))
  1633.         return TRUE;
  1634.     }
  1635.   
  1636.     if ((focus->win == NoneWin) ||
  1637.         (i >= spriteTraceGood) ||
  1638.         ((i > 0) && (pWin != spriteTrace[i-1])))
  1639.         return FALSE;
  1640.     }
  1641.         
  1642.     for (; i < spriteTraceGood; i++)
  1643.     {
  1644.     pWin = spriteTrace[i];
  1645.     if (pWin->optional &&
  1646.         CheckPassiveGrabsOnWindow(pWin, device, xE, count))
  1647.         return TRUE;
  1648.     }
  1649.  
  1650.     return FALSE;
  1651. }
  1652.  
  1653. void
  1654. DeliverFocusedEvent(keybd, xE, window, count)
  1655.     xEvent *xE;
  1656.     DeviceIntPtr keybd;
  1657.     WindowPtr window;
  1658.     int count;
  1659. {
  1660.     WindowPtr focus = keybd->focus->win;
  1661.     if (focus == FollowKeyboardWin)
  1662.     focus = inputInfo.keyboard->focus->win;
  1663.     if (!focus)
  1664.     return;
  1665.     if (focus == PointerRootWin)
  1666.     {
  1667.     DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
  1668.     return;
  1669.     }
  1670.     if ((focus == window) || IsParent(focus, window))
  1671.     {
  1672.     if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
  1673.         return;
  1674.     }
  1675.     /* just deliver it to the focus window */
  1676.     FixUpEventFromWindow(xE, focus, None, FALSE);
  1677.     (void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type],
  1678.                 NullGrab, 0);
  1679. }
  1680.  
  1681. void
  1682. DeliverGrabbedEvent(xE, thisDev, deactivateGrab, count)
  1683.     register xEvent *xE;
  1684.     register DeviceIntPtr thisDev;
  1685.     Bool deactivateGrab;
  1686.     int count;
  1687. {
  1688.     register GrabPtr grab = thisDev->grab;
  1689.     int deliveries = 0;
  1690.     register DeviceIntPtr dev;
  1691.     register xEvent *dxE;
  1692.  
  1693.     if (grab->ownerEvents)
  1694.     {
  1695.     WindowPtr focus;
  1696.  
  1697.     if (thisDev->focus)
  1698.     {
  1699.         focus = thisDev->focus->win;
  1700.         if (focus == FollowKeyboardWin)
  1701.         focus = inputInfo.keyboard->focus->win;
  1702.     }
  1703.     else
  1704.         focus = PointerRootWin;
  1705.     if (focus == PointerRootWin)
  1706.         deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow,
  1707.                          thisDev, count);
  1708.     else if (focus && (focus == sprite.win || IsParent(focus, sprite.win)))
  1709.         deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus,
  1710.                          thisDev, count);
  1711.     else if (focus)
  1712.         deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
  1713.                          thisDev, count);
  1714.     }
  1715.     if (!deliveries)
  1716.     {
  1717.     FixUpEventFromWindow(xE, grab->window, None, TRUE);
  1718.     deliveries = TryClientEvents(rClient(grab), xE, count,
  1719.                      (Mask)grab->eventMask,
  1720.                      filters[xE->u.u.type], grab);
  1721.     if (deliveries && (xE->u.u.type == MotionNotify))
  1722.         thisDev->valuator->motionHintWindow = grab->window;
  1723.     }
  1724.     if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify))
  1725.     switch (thisDev->sync.state)
  1726.     {
  1727.     case FREEZE_BOTH_NEXT_EVENT:
  1728.         for (dev = inputInfo.devices; dev; dev = dev->next)
  1729.         {
  1730.         if (dev == thisDev)
  1731.             continue;
  1732.         FreezeThaw(dev, TRUE);
  1733.         if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) &&
  1734.             (CLIENT_BITS(dev->grab->resource) ==
  1735.              CLIENT_BITS(thisDev->grab->resource)))
  1736.             dev->sync.state = FROZEN_NO_EVENT;
  1737.         else
  1738.             dev->sync.other = thisDev->grab;
  1739.         }
  1740.         /* fall through */
  1741.     case FREEZE_NEXT_EVENT:
  1742.         thisDev->sync.state = FROZEN_WITH_EVENT;
  1743.         FreezeThaw(thisDev, TRUE);
  1744.         thisDev->sync.event = (xEvent *)xrealloc(thisDev->sync.event,
  1745.                              count*sizeof(xEvent));
  1746.         thisDev->sync.evcount = count;
  1747.         for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
  1748.         *dxE = *xE;
  1749.         break;
  1750.     }
  1751. }
  1752.  
  1753. void
  1754. ProcessKeyboardEvent (xE, keybd, count)
  1755.     register xEvent *xE;
  1756.     register DeviceIntPtr keybd;
  1757.     int count;
  1758. {
  1759.     int             key, bit;
  1760.     register BYTE   *kptr;
  1761.     register int    i;
  1762.     register CARD8  modifiers;
  1763.     register CARD16 mask;
  1764.     GrabPtr         grab = keybd->grab;
  1765.     Bool            deactivateGrab = FALSE;
  1766.     register KeyClassPtr keyc = keybd->key;
  1767.  
  1768.     if (!syncEvents.playingEvents)
  1769.     NoticeTime(xE)
  1770.     xE->u.keyButtonPointer.state = (keyc->state |
  1771.                     inputInfo.pointer->button->state);
  1772.     xE->u.keyButtonPointer.rootX = sprite.hot.x;
  1773.     xE->u.keyButtonPointer.rootY = sprite.hot.y;
  1774.     key = xE->u.u.detail;
  1775.     kptr = &keyc->down[key >> 3];
  1776.     bit = 1 << (key & 7);
  1777.     modifiers = keyc->modifierMap[key];
  1778.     switch (xE->u.u.type)
  1779.     {
  1780.     case KeyPress: 
  1781.         if (*kptr & bit) /* allow ddx to generate multiple downs */
  1782.         {   
  1783.         if (!modifiers)
  1784.         {
  1785.             xE->u.u.type = KeyRelease;
  1786.             ProcessKeyboardEvent(xE, keybd, count);
  1787.             xE->u.u.type = KeyPress;
  1788.             /* release can have side effects, don't fall through */
  1789.             ProcessKeyboardEvent(xE, keybd, count);
  1790.         }
  1791.         return;
  1792.         }
  1793.         inputInfo.pointer->valuator->motionHintWindow = NullWindow;
  1794.         *kptr |= bit;
  1795.         for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
  1796.         {
  1797.         if (mask & modifiers)
  1798.         {
  1799.             /* This key affects modifier "i" */
  1800.             keyc->modifierKeyCount[i]++;
  1801.             keyc->state |= mask;
  1802.             modifiers &= ~mask;
  1803.         }
  1804.         }
  1805.         if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
  1806.         {
  1807.         keybd->activatingKey = key;
  1808.         return;
  1809.         }
  1810.         break;
  1811.     case KeyRelease: 
  1812.         if (!(*kptr & bit)) /* guard against duplicates */
  1813.         return;
  1814.         inputInfo.pointer->valuator->motionHintWindow = NullWindow;
  1815.         *kptr &= ~bit;
  1816.         for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
  1817.         {
  1818.         if (mask & modifiers) {
  1819.             /* This key affects modifier "i" */
  1820.             if (--keyc->modifierKeyCount[i] <= 0) {
  1821.             keyc->state &= ~mask;
  1822.             keyc->modifierKeyCount[i] = 0;
  1823.             }
  1824.             modifiers &= ~mask;
  1825.         }
  1826.         }
  1827.         if (keybd->fromPassiveGrab && (key == keybd->activatingKey))
  1828.         deactivateGrab = TRUE;
  1829.         break;
  1830.     default: 
  1831.         FatalError("Impossible keyboard event");
  1832.     }
  1833.     if (grab)
  1834.     DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
  1835.     else
  1836.     DeliverFocusedEvent(keybd, xE, sprite.win, count);
  1837.     if (deactivateGrab)
  1838.         (*keybd->DeactivateGrab)(keybd);
  1839. }
  1840.  
  1841. void
  1842. ProcessPointerEvent (xE, mouse, count)
  1843.     register xEvent         *xE;
  1844.     register DeviceIntPtr     mouse;
  1845.     int                count;
  1846. {
  1847.     register GrabPtr    grab = mouse->grab;
  1848.     Bool                deactivateGrab = FALSE;
  1849.     register ButtonClassPtr butc = mouse->button;
  1850.  
  1851.     if (!syncEvents.playingEvents)
  1852.     NoticeTime(xE)
  1853.     xE->u.keyButtonPointer.state = (butc->state |
  1854.                     inputInfo.keyboard->key->state);
  1855.     if (xE->u.u.type != MotionNotify)
  1856.     {
  1857.     register int  key;
  1858.     register BYTE *kptr;
  1859.     int           bit;
  1860.  
  1861.     xE->u.keyButtonPointer.rootX = sprite.hot.x;
  1862.     xE->u.keyButtonPointer.rootY = sprite.hot.y;
  1863.     key = xE->u.u.detail;
  1864.     kptr = &butc->down[key >> 3];
  1865.     bit = 1 << (key & 7);
  1866.     switch (xE->u.u.type)
  1867.     {
  1868.     case ButtonPress: 
  1869.         mouse->valuator->motionHintWindow = NullWindow;
  1870.         butc->buttonsDown++;
  1871.         butc->motionMask = ButtonMotionMask;
  1872.         *kptr |= bit;
  1873.         xE->u.u.detail = butc->map[key];
  1874.         if (xE->u.u.detail == 0)
  1875.         return;
  1876.         if (xE->u.u.detail <= 5)
  1877.         butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
  1878.         filters[MotionNotify] = Motion_Filter(butc);
  1879.         if (!grab)
  1880.         if (CheckDeviceGrabs(mouse, xE, 0, count))
  1881.             return;
  1882.         break;
  1883.     case ButtonRelease: 
  1884.         mouse->valuator->motionHintWindow = NullWindow;
  1885.         if (!--butc->buttonsDown)
  1886.         butc->motionMask = 0;
  1887.         *kptr &= ~bit;
  1888.         xE->u.u.detail = butc->map[key];
  1889.         if (xE->u.u.detail == 0)
  1890.         return;
  1891.         if (xE->u.u.detail <= 5)
  1892.         butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
  1893.         filters[MotionNotify] = Motion_Filter(butc);
  1894.         if (!butc->state && mouse->fromPassiveGrab)
  1895.         deactivateGrab = TRUE;
  1896.         break;
  1897.     default: 
  1898.         FatalError("bogus pointer event from ddx");
  1899.     }
  1900.     }
  1901.     else if (!CheckMotion(xE))
  1902.     return;
  1903.     if (grab)
  1904.     DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
  1905.     else
  1906.     DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
  1907.                 mouse, count);
  1908.     if (deactivateGrab)
  1909.         (*mouse->DeactivateGrab)(mouse);
  1910. }
  1911.  
  1912. #define AtMostOneClient \
  1913.     (SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
  1914.  
  1915. void
  1916. RecalculateDeliverableEvents(pWin)
  1917.     register WindowPtr pWin;
  1918. {
  1919.     register OtherClients *others;
  1920.     register WindowPtr pChild;
  1921.  
  1922.     pChild = pWin;
  1923.     while (1)
  1924.     {
  1925.     for (others = wOtherClients(pChild); others; others = others->next)
  1926.     {
  1927.         if (others->mask)
  1928.         pChild->optional->otherEventMasks |= others->mask;
  1929.     }
  1930.     pChild->deliverableEvents = pChild->eventMask|
  1931.                     wOtherEventMasks(pChild);
  1932.     if (pChild->parent)
  1933.         pChild->deliverableEvents |=
  1934.         (pChild->parent->deliverableEvents &
  1935.          ~wDontPropagateMask(pChild) & PropagateMask);
  1936.     if (pChild->firstChild)
  1937.     {
  1938.         pChild = pChild->firstChild;
  1939.         continue;
  1940.     }
  1941.     while (!pChild->nextSib && (pChild != pWin))
  1942.         pChild = pChild->parent;
  1943.     if (pChild == pWin)
  1944.         break;
  1945.     pChild = pChild->nextSib;
  1946.     }
  1947. }
  1948.  
  1949. int
  1950. OtherClientGone(pWin, id)
  1951.     register WindowPtr pWin;
  1952.     XID   id;
  1953. {
  1954.     register OtherClientsPtr other, prev;
  1955.  
  1956.     prev = 0;
  1957.     for (other = wOtherClients(pWin); other; other = other->next)
  1958.     {
  1959.     if (other->resource == id)
  1960.     {
  1961.         if (prev)
  1962.         prev->next = other->next;
  1963.         else
  1964.         {
  1965.         if (!(pWin->optional->otherClients = other->next))
  1966.             CheckWindowOptionalNeed (pWin);
  1967.         }
  1968.         xfree(other);
  1969.         RecalculateDeliverableEvents(pWin);
  1970.         return(Success);
  1971.     }
  1972.     prev = other;
  1973.     }
  1974.     FatalError("client not on event list");
  1975.     /*NOTREACHED*/
  1976. }
  1977.  
  1978. int
  1979. EventSelectForWindow(pWin, client, mask)
  1980.     register WindowPtr pWin;
  1981.     register ClientPtr client;
  1982.     Mask mask;
  1983. {
  1984.     Mask check;
  1985.     OtherClients * others;
  1986.  
  1987.     if (mask & ~AllEventMasks)
  1988.     {
  1989.     client->errorValue = mask;
  1990.     return BadValue;
  1991.     }
  1992.     check = (mask & AtMostOneClient);
  1993.     if (check & (pWin->eventMask|wOtherEventMasks(pWin)))
  1994.     {                       /* It is illegal for two different
  1995.                           clients to select on any of the
  1996.                           events for AtMostOneClient. However,
  1997.                           it is OK, for some client to
  1998.                           continue selecting on one of those
  1999.                           events.  */
  2000.     if ((wClient(pWin) != client) && (check & pWin->eventMask))
  2001.         return BadAccess;
  2002.     for (others = wOtherClients (pWin); others; others = others->next)
  2003.     {
  2004.         if (!SameClient(others, client) && (check & others->mask))
  2005.         return BadAccess;
  2006.     }
  2007.     }
  2008.     if (wClient (pWin) == client)
  2009.     {
  2010.     check = pWin->eventMask;
  2011.     pWin->eventMask = mask;
  2012.     }
  2013.     else
  2014.     {
  2015.     for (others = wOtherClients (pWin); others; others = others->next)
  2016.     {
  2017.         if (SameClient(others, client))
  2018.         {
  2019.         check = others->mask;
  2020.         if (mask == 0)
  2021.         {
  2022.             FreeResource(others->resource, RT_NONE);
  2023.             return Success;
  2024.         }
  2025.         else
  2026.             others->mask = mask;
  2027.         goto maskSet;
  2028.         }
  2029.     }
  2030.     check = 0;
  2031.     if (!pWin->optional && !MakeWindowOptional (pWin))
  2032.         return BadAlloc;
  2033.     others = (OtherClients *) xalloc(sizeof(OtherClients));
  2034.     if (!others)
  2035.         return BadAlloc;
  2036.     others->mask = mask;
  2037.     others->resource = FakeClientID(client->index);
  2038.     others->next = pWin->optional->otherClients;
  2039.     pWin->optional->otherClients = others;
  2040.     if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer)pWin))
  2041.         return BadAlloc;
  2042.     }
  2043. maskSet: 
  2044.     if ((inputInfo.pointer->valuator->motionHintWindow == pWin) &&
  2045.     (mask & PointerMotionHintMask) &&
  2046.     !(check & PointerMotionHintMask) &&
  2047.     !inputInfo.pointer->grab)
  2048.     inputInfo.pointer->valuator->motionHintWindow = NullWindow;
  2049.     RecalculateDeliverableEvents(pWin);
  2050.     return Success;
  2051. }
  2052.  
  2053. /*ARGSUSED*/
  2054. int
  2055. EventSuppressForWindow(pWin, client, mask, checkOptional)
  2056.     register WindowPtr pWin;
  2057.     register ClientPtr client;
  2058.     Mask mask;
  2059.     Bool *checkOptional;
  2060. {
  2061.     register int i, free;
  2062.  
  2063.     if ((mask & ~PropagateMask) && !permitOldBugs)
  2064.     {
  2065.     client->errorValue = mask;
  2066.     return BadValue;
  2067.     }
  2068.     if (pWin->dontPropagate)
  2069.     DontPropagateRefCnts[pWin->dontPropagate]--;
  2070.     if (!mask)
  2071.     i = 0;
  2072.     else
  2073.     {
  2074.     for (i = DNPMCOUNT, free = 0; --i > 0; )
  2075.     {
  2076.         if (!DontPropagateRefCnts[i])
  2077.         free = i;
  2078.         else if (mask == DontPropagateMasks[i])
  2079.         break;
  2080.     }
  2081.     if (!i && free)
  2082.     {
  2083.         i = free;
  2084.         DontPropagateMasks[i] = mask;
  2085.     }
  2086.     }
  2087.     if (i || !mask)
  2088.     {
  2089.     pWin->dontPropagate = i;
  2090.     if (i)
  2091.         DontPropagateRefCnts[i]++;
  2092.     if (pWin->optional)
  2093.     {
  2094.         pWin->optional->dontPropagateMask = mask;
  2095.         *checkOptional = TRUE;
  2096.     }
  2097.     }
  2098.     else
  2099.     {
  2100.     if (!pWin->optional && !MakeWindowOptional (pWin))
  2101.     {
  2102.         if (pWin->dontPropagate)
  2103.         DontPropagateRefCnts[pWin->dontPropagate]++;
  2104.         return BadAlloc;
  2105.     }
  2106.     pWin->dontPropagate = 0;
  2107.         pWin->optional->dontPropagateMask = mask;
  2108.     }
  2109.     RecalculateDeliverableEvents(pWin);
  2110.     return Success;
  2111. }
  2112.  
  2113. static WindowPtr 
  2114. CommonAncestor(a, b)
  2115.     register WindowPtr a, b;
  2116. {
  2117.     for (b = b->parent; b; b = b->parent)
  2118.     if (IsParent(b, a)) return b;
  2119.     return NullWindow;
  2120. }
  2121.  
  2122. static void
  2123. EnterLeaveEvent(type, mode, detail, pWin)
  2124.     int type, mode, detail;
  2125.     register WindowPtr pWin;
  2126. {
  2127.     xEvent        event;
  2128.     register DeviceIntPtr keybd = inputInfo.keyboard;
  2129.     WindowPtr        focus;
  2130.     register DeviceIntPtr mouse = inputInfo.pointer;
  2131.     register GrabPtr    grab = mouse->grab;
  2132.     Mask        mask;
  2133.  
  2134.     if ((pWin == mouse->valuator->motionHintWindow) &&
  2135.     (detail != NotifyInferior))
  2136.     mouse->valuator->motionHintWindow = NullWindow;
  2137.     if (grab)
  2138.     {
  2139.     mask = (pWin == grab->window) ? grab->eventMask : 0;
  2140.     if (grab->ownerEvents)
  2141.         mask |= EventMaskForClient(pWin, rClient(grab));
  2142.     }
  2143.     else
  2144.     {
  2145.     mask = pWin->eventMask | wOtherEventMasks(pWin);
  2146.     }
  2147.     if (mask & filters[type])
  2148.     {
  2149.     event.u.u.type = type;
  2150.     event.u.u.detail = detail;
  2151.     event.u.enterLeave.time = currentTime.milliseconds;
  2152.     event.u.enterLeave.rootX = sprite.hot.x;
  2153.     event.u.enterLeave.rootY = sprite.hot.y;
  2154.     /* Counts on the same initial structure of crossing & button events! */
  2155.     FixUpEventFromWindow(&event, pWin, None, TRUE);        
  2156.     event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
  2157.                         ELFlagSameScreen : 0;
  2158.     event.u.enterLeave.state = keybd->key->state | mouse->button->state;
  2159.     event.u.enterLeave.mode = mode;
  2160.     focus = keybd->focus->win;
  2161.     if ((focus != NoneWin) &&
  2162.         ((pWin == focus) || (focus == PointerRootWin) ||
  2163.          IsParent(focus, pWin)))
  2164.         event.u.enterLeave.flags |= ELFlagFocus;
  2165.     if (grab)
  2166.         (void)TryClientEvents(rClient(grab), &event, 1, mask,
  2167.                   filters[type], grab);
  2168.     else
  2169.         (void)DeliverEventsToWindow(pWin, &event, 1, filters[type],
  2170.                     NullGrab, 0);
  2171.     }
  2172.     if ((type == EnterNotify) && (mask & KeymapStateMask))
  2173.     {
  2174.     xKeymapEvent ke;
  2175.     ke.type = KeymapNotify;
  2176.     bcopy((char *)&keybd->key->down[1], (char *)&ke.map[0], 31);
  2177.     if (grab)
  2178.         (void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask,
  2179.                   KeymapStateMask, grab);
  2180.     else
  2181.         (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
  2182.                     KeymapStateMask, NullGrab, 0);
  2183.     }
  2184. }
  2185.  
  2186. static void
  2187. EnterNotifies(ancestor, child, mode, detail)
  2188.     WindowPtr ancestor, child;
  2189.     int mode, detail;
  2190. {
  2191.     if (!child || (ancestor == child))
  2192.     return;
  2193.     EnterNotifies(ancestor, child->parent, mode, detail);
  2194.     EnterLeaveEvent(EnterNotify, mode, detail, child);
  2195. }
  2196.  
  2197. /* dies horribly if ancestor is not an ancestor of child */
  2198. static void
  2199. LeaveNotifies(child, ancestor, mode, detail)
  2200.     WindowPtr child, ancestor;
  2201.     int detail, mode;
  2202. {
  2203.     register WindowPtr  pWin;
  2204.  
  2205.     if (ancestor == child)
  2206.     return;
  2207.     for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent)
  2208.     EnterLeaveEvent(LeaveNotify, mode, detail, pWin);
  2209. }
  2210.  
  2211. static void
  2212. DoEnterLeaveEvents(fromWin, toWin, mode)
  2213.     WindowPtr fromWin, toWin;
  2214.     int mode;
  2215. {
  2216.     if (fromWin == toWin)
  2217.     return;
  2218.     if (IsParent(fromWin, toWin))
  2219.     {
  2220.     EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin);
  2221.     EnterNotifies(fromWin, toWin->parent, mode, NotifyVirtual);
  2222.     EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin);
  2223.     }
  2224.     else if (IsParent(toWin, fromWin))
  2225.     {
  2226.     EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin);
  2227.     LeaveNotifies(fromWin, toWin, mode, NotifyVirtual);
  2228.     EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin);
  2229.     }
  2230.     else
  2231.     { /* neither fromWin nor toWin is descendent of the other */
  2232.     WindowPtr common = CommonAncestor(toWin, fromWin);
  2233.     /* common == NullWindow ==> different screens */
  2234.     EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin);
  2235.     LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual);
  2236.     EnterNotifies(common, toWin->parent, mode, NotifyNonlinearVirtual);
  2237.     EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin);
  2238.     }
  2239. }
  2240.  
  2241. static void
  2242. FocusEvent(dev, type, mode, detail, pWin)
  2243.     DeviceIntPtr dev;
  2244.     int type, mode, detail;
  2245.     register WindowPtr pWin;
  2246. {
  2247.     xEvent event;
  2248.  
  2249. #ifdef XINPUT
  2250.     if (dev != inputInfo.keyboard)
  2251.     {
  2252.     DeviceFocusEvent(dev, type, mode, detail, pWin);
  2253.     return;
  2254.     }
  2255. #endif
  2256.     event.u.focus.mode = mode;
  2257.     event.u.u.type = type;
  2258.     event.u.u.detail = detail;
  2259.     event.u.focus.window = pWin->drawable.id;
  2260.     (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab,
  2261.                 0);
  2262.     if ((type == FocusIn) &&
  2263.     ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
  2264.     {
  2265.     xKeymapEvent ke;
  2266.     ke.type = KeymapNotify;
  2267.     bcopy((char *)dev->key->down, (char *)&ke.map[0], 31);
  2268.     (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
  2269.                     KeymapStateMask, NullGrab, 0);
  2270.     }
  2271. }
  2272.  
  2273.  /*
  2274.   * recursive because it is easier
  2275.   * no-op if child not descended from ancestor
  2276.   */
  2277. static Bool
  2278. FocusInEvents(dev, ancestor, child, skipChild, mode, detail, doAncestor)
  2279.     DeviceIntPtr dev;
  2280.     WindowPtr ancestor, child, skipChild;
  2281.     int mode, detail;
  2282.     Bool doAncestor;
  2283. {
  2284.     if (child == NullWindow)
  2285.     return ancestor == NullWindow;
  2286.     if (ancestor == child)
  2287.     {
  2288.     if (doAncestor)
  2289.         FocusEvent(dev, FocusIn, mode, detail, child);
  2290.     return TRUE;
  2291.     }
  2292.     if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail,
  2293.               doAncestor))
  2294.     {
  2295.     if (child != skipChild)
  2296.         FocusEvent(dev, FocusIn, mode, detail, child);
  2297.     return TRUE;
  2298.     }
  2299.     return FALSE;
  2300. }
  2301.  
  2302. /* dies horribly if ancestor is not an ancestor of child */
  2303. static void
  2304. FocusOutEvents(dev, child, ancestor, mode, detail, doAncestor)
  2305.     DeviceIntPtr dev;
  2306.     WindowPtr child, ancestor;
  2307.     int detail;
  2308.     Bool doAncestor;
  2309. {
  2310.     register WindowPtr  pWin;
  2311.  
  2312.     for (pWin = child; pWin != ancestor; pWin = pWin->parent)
  2313.     FocusEvent(dev, FocusOut, mode, detail, pWin);
  2314.     if (doAncestor)
  2315.     FocusEvent(dev, FocusOut, mode, detail, ancestor);
  2316. }
  2317.  
  2318. void
  2319. DoFocusEvents(dev, fromWin, toWin, mode)
  2320.     DeviceIntPtr dev;
  2321.     WindowPtr fromWin, toWin;
  2322.     int mode;
  2323. {
  2324.     int     out, in;               /* for holding details for to/from
  2325.                           PointerRoot/None */
  2326.     int     i;
  2327.  
  2328.     if (fromWin == toWin)
  2329.     return;
  2330.     out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
  2331.     in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
  2332.  /* wrong values if neither, but then not referenced */
  2333.  
  2334.     if ((toWin == NullWindow) || (toWin == PointerRootWin))
  2335.     {
  2336.     if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
  2337.        {
  2338.         if (fromWin == PointerRootWin)
  2339.         FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
  2340.                    TRUE);
  2341.         /* Notify all the roots */
  2342.         for (i=0; i<screenInfo.numScreens; i++)
  2343.             FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
  2344.     }
  2345.     else
  2346.     {
  2347.         if (IsParent(fromWin, sprite.win))
  2348.           FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer,
  2349.                  FALSE);
  2350.         FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
  2351.         /* next call catches the root too, if the screen changed */
  2352.         FocusOutEvents(dev, fromWin->parent, NullWindow, mode,
  2353.                NotifyNonlinearVirtual, FALSE);
  2354.     }
  2355.     /* Notify all the roots */
  2356.     for (i=0; i<screenInfo.numScreens; i++)
  2357.         FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
  2358.     if (toWin == PointerRootWin)
  2359.         (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
  2360.                 NotifyPointer, TRUE);
  2361.     }
  2362.     else
  2363.     {
  2364.     if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
  2365.     {
  2366.         if (fromWin == PointerRootWin)
  2367.         FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
  2368.                    TRUE);
  2369.         for (i=0; i<screenInfo.numScreens; i++)
  2370.           FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
  2371.         if (toWin->parent != NullWindow)
  2372.           (void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
  2373.                   NotifyNonlinearVirtual, TRUE);
  2374.         FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
  2375.         if (IsParent(toWin, sprite.win))
  2376.                (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, mode,
  2377.                    NotifyPointer, FALSE);
  2378.     }
  2379.     else
  2380.     {
  2381.         if (IsParent(toWin, fromWin))
  2382.         {
  2383.         FocusEvent(dev, FocusOut, mode, NotifyAncestor, fromWin);
  2384.         FocusOutEvents(dev, fromWin->parent, toWin, mode,
  2385.                    NotifyVirtual, FALSE);
  2386.         FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin);
  2387.         if ((IsParent(toWin, sprite.win)) &&
  2388.             (sprite.win != fromWin) &&
  2389.             (!IsParent(fromWin, sprite.win)) &&
  2390.             (!IsParent(sprite.win, fromWin)))
  2391.             (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
  2392.                     mode, NotifyPointer, FALSE);
  2393.         }
  2394.         else
  2395.         if (IsParent(fromWin, toWin))
  2396.         {
  2397.             if ((IsParent(fromWin, sprite.win)) &&
  2398.                 (sprite.win != fromWin) &&
  2399.                 (!IsParent(toWin, sprite.win)) &&
  2400.                 (!IsParent(sprite.win, toWin)))
  2401.             FocusOutEvents(dev, sprite.win, fromWin, mode,
  2402.                        NotifyPointer, FALSE);
  2403.             FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin);
  2404.             (void)FocusInEvents(dev, fromWin, toWin, toWin, mode,
  2405.                     NotifyVirtual, FALSE);
  2406.             FocusEvent(dev, FocusIn, mode, NotifyAncestor, toWin);
  2407.         }
  2408.         else
  2409.         {
  2410.         /* neither fromWin or toWin is child of other */
  2411.             WindowPtr common = CommonAncestor(toWin, fromWin);
  2412.         /* common == NullWindow ==> different screens */
  2413.             if (IsParent(fromWin, sprite.win))
  2414.             FocusOutEvents(dev, sprite.win, fromWin, mode,
  2415.                        NotifyPointer, FALSE);
  2416.             FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
  2417.             if (fromWin->parent != NullWindow)
  2418.               FocusOutEvents(dev, fromWin->parent, common, mode,
  2419.                      NotifyNonlinearVirtual, FALSE);
  2420.             if (toWin->parent != NullWindow)
  2421.               (void)FocusInEvents(dev, common, toWin, toWin, mode,
  2422.                       NotifyNonlinearVirtual, FALSE);
  2423.             FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
  2424.             if (IsParent(toWin, sprite.win))
  2425.             (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
  2426.                         mode, NotifyPointer, FALSE);
  2427.         }
  2428.     }
  2429.     }
  2430. }
  2431.  
  2432. int
  2433. SetInputFocus(client, dev, focusID, revertTo, ctime, followOK)
  2434.     ClientPtr client;
  2435.     DeviceIntPtr dev;
  2436.     Window focusID;
  2437.     CARD8 revertTo;
  2438.     Time ctime;
  2439.     Bool followOK;
  2440. {
  2441.     register FocusClassPtr focus;
  2442.     register WindowPtr focusWin;
  2443.     int mode;
  2444.     TimeStamp time;
  2445.  
  2446.     UpdateCurrentTime();
  2447.     if ((revertTo != RevertToParent) &&
  2448.     (revertTo != RevertToPointerRoot) &&
  2449.     (revertTo != RevertToNone) &&
  2450.     ((revertTo != RevertToFollowKeyboard) || !followOK))
  2451.     {
  2452.     client->errorValue = revertTo;
  2453.     return BadValue;
  2454.     }
  2455.     time = ClientTimeToServerTime(ctime);
  2456.     if ((focusID == None) || (focusID == PointerRoot))
  2457.     focusWin = (WindowPtr)focusID;
  2458.     else if ((focusID == FollowKeyboard) && followOK)
  2459.     focusWin = inputInfo.keyboard->focus->win;
  2460.     else if (!(focusWin = LookupWindow(focusID, client)))
  2461.     return BadWindow;
  2462.     else
  2463.     {
  2464.      /* It is a match error to try to set the input focus to an 
  2465.     unviewable window. */
  2466.  
  2467.     if(!focusWin->realized)
  2468.         return(BadMatch);
  2469.     }
  2470.     focus = dev->focus;
  2471.     if ((CompareTimeStamps(time, currentTime) == LATER) ||
  2472.     (CompareTimeStamps(time, focus->time) == EARLIER))
  2473.     return Success;
  2474.     mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
  2475.     if (focus->win == FollowKeyboardWin)
  2476.     DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
  2477.     else
  2478.     DoFocusEvents(dev, focus->win, focusWin, mode);
  2479.     focus->time = time;
  2480.     focus->revert = revertTo;
  2481.     if (focusID == FollowKeyboard)
  2482.     focus->win = FollowKeyboardWin;
  2483.     else
  2484.     focus->win = focusWin;
  2485.     if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
  2486.     focus->traceGood = 0;
  2487.     else
  2488.     {
  2489.         int depth = 0;
  2490.     register WindowPtr pWin;
  2491.  
  2492.         for (pWin = focusWin; pWin; pWin = pWin->parent) depth++;
  2493.         if (depth > focus->traceSize)
  2494.         {
  2495.         focus->traceSize = depth+1;
  2496.         focus->trace = (WindowPtr *)xrealloc(focus->trace,
  2497.                          focus->traceSize *
  2498.                          sizeof(WindowPtr));
  2499.         if (!focus->trace)
  2500.         FatalError("could not realloc focus trace"); /* XXX */
  2501.     }
  2502.     focus->traceGood = depth;
  2503.         for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--) 
  2504.         focus->trace[depth] = pWin;
  2505.     }
  2506.     return Success;
  2507. }
  2508.  
  2509. int
  2510. ProcSetInputFocus(client)
  2511.     ClientPtr client;
  2512. {
  2513.     REQUEST(xSetInputFocusReq);
  2514.  
  2515.     REQUEST_SIZE_MATCH(xSetInputFocusReq);
  2516.     return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
  2517.              stuff->revertTo, stuff->time, FALSE);
  2518. }
  2519.  
  2520. int
  2521. ProcGetInputFocus(client)
  2522.     ClientPtr client;
  2523. {
  2524.     xGetInputFocusReply rep;
  2525.     REQUEST(xReq);
  2526.     FocusClassPtr focus = inputInfo.keyboard->focus;
  2527.  
  2528.     REQUEST_SIZE_MATCH(xReq);
  2529.     rep.type = X_Reply;
  2530.     rep.length = 0;
  2531.     rep.sequenceNumber = client->sequence;
  2532.     if (focus->win == NoneWin)
  2533.     rep.focus = None;
  2534.     else if (focus->win == PointerRootWin)
  2535.     rep.focus = PointerRoot;
  2536.     else rep.focus = focus->win->drawable.id;
  2537.     rep.revertTo = focus->revert;
  2538.     WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
  2539.     return Success;
  2540. }
  2541.  
  2542. int
  2543. ProcGrabPointer(client)
  2544.     ClientPtr client;
  2545. {
  2546.     xGrabPointerReply rep;
  2547.     DeviceIntPtr device = inputInfo.pointer;
  2548.     GrabPtr grab;
  2549.     WindowPtr pWin, confineTo;
  2550.     CursorPtr cursor;
  2551.     REQUEST(xGrabPointerReq);
  2552.     TimeStamp time;
  2553.  
  2554.     REQUEST_SIZE_MATCH(xGrabPointerReq);
  2555.     UpdateCurrentTime();
  2556.     if ((stuff->pointerMode != GrabModeSync) &&
  2557.     (stuff->pointerMode != GrabModeAsync))
  2558.     {
  2559.     client->errorValue = stuff->pointerMode;
  2560.         return BadValue;
  2561.     }
  2562.     if ((stuff->keyboardMode != GrabModeSync) &&
  2563.     (stuff->keyboardMode != GrabModeAsync))
  2564.     {
  2565.     client->errorValue = stuff->keyboardMode;
  2566.         return BadValue;
  2567.     }
  2568.     if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
  2569.     {
  2570.     client->errorValue = stuff->ownerEvents;
  2571.         return BadValue;
  2572.     }
  2573.     if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
  2574.     {
  2575.     client->errorValue = stuff->eventMask;
  2576.         return BadValue;
  2577.     }
  2578.     pWin = LookupWindow(stuff->grabWindow, client);
  2579.     if (!pWin)
  2580.     return BadWindow;
  2581.     if (stuff->confineTo == None)
  2582.     confineTo = NullWindow;
  2583.     else
  2584.     {
  2585.     confineTo = LookupWindow(stuff->confineTo, client);
  2586.     if (!confineTo)
  2587.         return BadWindow;
  2588.     }
  2589.     if (stuff->cursor == None)
  2590.     cursor = NullCursor;
  2591.     else
  2592.     {
  2593.     cursor = (CursorPtr)LookupIDByType(stuff->cursor, RT_CURSOR);
  2594.     if (!cursor)
  2595.     {
  2596.         client->errorValue = stuff->cursor;
  2597.         return BadCursor;
  2598.     }
  2599.     }
  2600.     /* at this point, some sort of reply is guaranteed. */
  2601.     time = ClientTimeToServerTime(stuff->time);
  2602.     rep.type = X_Reply;
  2603.     rep.sequenceNumber = client->sequence;
  2604.     rep.length = 0;
  2605.     grab = device->grab;
  2606.     if ((grab) && !SameClient(grab, client))
  2607.     rep.status = AlreadyGrabbed;
  2608.     else if ((!pWin->realized) ||
  2609.          (confineTo &&
  2610.         !(confineTo->realized &&
  2611.           (* confineTo->drawable.pScreen->RegionNotEmpty)
  2612.             (&confineTo->borderSize))))
  2613.     rep.status = GrabNotViewable;
  2614.     else if (device->sync.frozen &&
  2615.          device->sync.other && !SameClient(device->sync.other, client))
  2616.     rep.status = GrabFrozen;
  2617.     else if ((CompareTimeStamps(time, currentTime) == LATER) ||
  2618.          (grab && (CompareTimeStamps(time, device->grabTime) == EARLIER)))
  2619.     rep.status = GrabInvalidTime;
  2620.     else
  2621.     {
  2622.     GrabRec tempGrab;
  2623.  
  2624.     if (grab && grab->confineTo && !confineTo)
  2625.         ConfineCursorToWindow(ROOT, FALSE);
  2626.     tempGrab.cursor = cursor;
  2627.     tempGrab.resource = client->clientAsMask;
  2628.     tempGrab.ownerEvents = stuff->ownerEvents;
  2629.     tempGrab.eventMask = stuff->eventMask;
  2630.     tempGrab.confineTo = confineTo;
  2631.     tempGrab.window = pWin;
  2632.     tempGrab.keyboardMode = stuff->keyboardMode;
  2633.     tempGrab.pointerMode = stuff->pointerMode;
  2634.     tempGrab.device = device;
  2635.     (*device->ActivateGrab)(device, &tempGrab, time, FALSE);
  2636.     rep.status = GrabSuccess;
  2637.     }
  2638.     WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
  2639.     return Success;
  2640. }
  2641.  
  2642. int
  2643. ProcChangeActivePointerGrab(client)
  2644.     ClientPtr client;
  2645. {
  2646.     DeviceIntPtr device = inputInfo.pointer;
  2647.     register GrabPtr grab = device->grab;
  2648.     CursorPtr newCursor;
  2649.     REQUEST(xChangeActivePointerGrabReq);
  2650.     TimeStamp time;
  2651.  
  2652.     REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
  2653.     if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
  2654.     {
  2655.     client->errorValue = stuff->eventMask;
  2656.         return BadValue;
  2657.     }
  2658.     if (stuff->cursor == None)
  2659.     newCursor = NullCursor;
  2660.     else
  2661.     {
  2662.     newCursor = (CursorPtr)LookupIDByType(stuff->cursor, RT_CURSOR);
  2663.     if (!newCursor)
  2664.     {
  2665.         client->errorValue = stuff->cursor;
  2666.         return BadCursor;
  2667.     }
  2668.     }
  2669.     if (!grab)
  2670.     return Success;
  2671.     if (!SameClient(grab, client))
  2672.     return BadAccess;
  2673.     time = ClientTimeToServerTime(stuff->time);
  2674.     if ((CompareTimeStamps(time, currentTime) == LATER) ||
  2675.          (CompareTimeStamps(time, device->grabTime) == EARLIER))
  2676.     return Success;
  2677.     if (grab->cursor)
  2678.     FreeCursor(grab->cursor, (Cursor)0);
  2679.     grab->cursor = newCursor;
  2680.     if (newCursor)
  2681.     newCursor->refcnt++;
  2682.     PostNewCursor();
  2683.     grab->eventMask = stuff->eventMask;
  2684.     return Success;
  2685. }
  2686.  
  2687. int
  2688. ProcUngrabPointer(client)
  2689.     ClientPtr client;
  2690. {
  2691.     DeviceIntPtr device = inputInfo.pointer;
  2692.     GrabPtr grab;
  2693.     TimeStamp time;
  2694.     REQUEST(xResourceReq);
  2695.  
  2696.     REQUEST_SIZE_MATCH(xResourceReq);
  2697.     UpdateCurrentTime();
  2698.     grab = device->grab;
  2699.     time = ClientTimeToServerTime(stuff->id);
  2700.     if ((CompareTimeStamps(time, currentTime) != LATER) &&
  2701.         (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
  2702.         (grab) && SameClient(grab, client))
  2703.     (*device->DeactivateGrab)(device);
  2704.     return Success;
  2705. }
  2706.  
  2707. int
  2708. GrabDevice(client, dev, this_mode, other_mode, grabWindow, ownerEvents, ctime,
  2709.        mask, status)
  2710.     register ClientPtr client;
  2711.     register DeviceIntPtr dev;
  2712.     unsigned this_mode;
  2713.     unsigned other_mode;
  2714.     Window grabWindow;
  2715.     unsigned ownerEvents;
  2716.     Time ctime;
  2717.     Mask mask;
  2718.     CARD8 *status;
  2719. {
  2720.     register WindowPtr pWin;
  2721.     register GrabPtr grab;
  2722.     TimeStamp time;
  2723.  
  2724.     UpdateCurrentTime();
  2725.     if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
  2726.     {
  2727.     client->errorValue = this_mode;
  2728.         return BadValue;
  2729.     }
  2730.     if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync))
  2731.     {
  2732.     client->errorValue = other_mode;
  2733.         return BadValue;
  2734.     }
  2735.     if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
  2736.     {
  2737.     client->errorValue = ownerEvents;
  2738.         return BadValue;
  2739.     }
  2740.     pWin = LookupWindow(grabWindow, client);
  2741.     if (!pWin)
  2742.     return BadWindow;
  2743.     time = ClientTimeToServerTime(ctime);
  2744.     grab = dev->grab;
  2745.     if (grab && !SameClient(grab, client))
  2746.     *status = AlreadyGrabbed;
  2747.     else if (!pWin->realized)
  2748.     *status = GrabNotViewable;
  2749.     else if ((CompareTimeStamps(time, currentTime) == LATER) ||
  2750.          (grab && (CompareTimeStamps(time, dev->grabTime) == EARLIER)))
  2751.     *status = GrabInvalidTime;
  2752.     else if (dev->sync.frozen &&
  2753.          dev->sync.other && !SameClient(dev->sync.other, client))
  2754.     *status = GrabFrozen;
  2755.     else
  2756.     {
  2757.     GrabRec tempGrab;
  2758.  
  2759.     tempGrab.window = pWin;
  2760.     tempGrab.resource = client->clientAsMask;
  2761.     tempGrab.ownerEvents = ownerEvents;
  2762.     tempGrab.keyboardMode = this_mode;
  2763.     tempGrab.pointerMode = other_mode;
  2764.     tempGrab.eventMask = mask;
  2765.     tempGrab.device = dev;
  2766.     (*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
  2767.     *status = GrabSuccess;
  2768.     }
  2769.     return Success;
  2770. }
  2771.  
  2772. int
  2773. ProcGrabKeyboard(client)
  2774.     ClientPtr client;
  2775. {
  2776.     xGrabKeyboardReply rep;
  2777.     REQUEST(xGrabKeyboardReq);
  2778.     int result;
  2779.  
  2780.     REQUEST_SIZE_MATCH(xGrabKeyboardReq);
  2781.     result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
  2782.             stuff->pointerMode, stuff->grabWindow,
  2783.             stuff->ownerEvents, stuff->time,
  2784.             KeyPressMask | KeyReleaseMask, &rep.status);
  2785.     if (result != Success)
  2786.     return result;
  2787.     rep.type = X_Reply;
  2788.     rep.sequenceNumber = client->sequence;
  2789.     rep.length = 0;
  2790.     WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
  2791.     return Success;
  2792. }
  2793.  
  2794. int
  2795. ProcUngrabKeyboard(client)
  2796.     ClientPtr client;
  2797. {
  2798.     DeviceIntPtr device = inputInfo.keyboard;
  2799.     GrabPtr grab;
  2800.     TimeStamp time;
  2801.     REQUEST(xResourceReq);
  2802.  
  2803.     REQUEST_SIZE_MATCH(xResourceReq);
  2804.     UpdateCurrentTime();
  2805.     grab = device->grab;
  2806.     time = ClientTimeToServerTime(stuff->id);
  2807.     if ((CompareTimeStamps(time, currentTime) != LATER) &&
  2808.     (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
  2809.     (grab) && SameClient(grab, client))
  2810.     (*device->DeactivateGrab)(device);
  2811.     return Success;
  2812. }
  2813.  
  2814. int
  2815. ProcQueryPointer(client)
  2816.     ClientPtr client;
  2817. {
  2818.     xQueryPointerReply rep;
  2819.     WindowPtr pWin, t;
  2820.     REQUEST(xResourceReq);
  2821.     DeviceIntPtr mouse = inputInfo.pointer;
  2822.  
  2823.     REQUEST_SIZE_MATCH(xResourceReq);
  2824.     pWin = LookupWindow(stuff->id, client);
  2825.     if (!pWin)
  2826.     return BadWindow;
  2827.     if (mouse->valuator->motionHintWindow)
  2828.     MaybeStopHint(mouse, client);
  2829.     rep.type = X_Reply;
  2830.     rep.sequenceNumber = client->sequence;
  2831.     rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
  2832.     rep.length = 0;
  2833.     rep.root = (ROOT)->drawable.id;
  2834.     rep.rootX = sprite.hot.x;
  2835.     rep.rootY = sprite.hot.y;
  2836.     rep.child = None;
  2837.     if (sprite.hot.pScreen == pWin->drawable.pScreen)
  2838.     {
  2839.     rep.sameScreen = xTrue;
  2840.     rep.winX = sprite.hot.x - pWin->drawable.x;
  2841.     rep.winY = sprite.hot.y - pWin->drawable.y;
  2842.     for (t = sprite.win; t; t = t->parent)
  2843.         if (t->parent == pWin)
  2844.         {
  2845.         rep.child = t->drawable.id;
  2846.         break;
  2847.         }
  2848.     }
  2849.     else
  2850.     {
  2851.     rep.sameScreen = xFalse;
  2852.     rep.winX = 0;
  2853.     rep.winY = 0;
  2854.     }
  2855.     WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
  2856.  
  2857.     return(Success);    
  2858. }
  2859.  
  2860. void
  2861. InitEvents()
  2862. {
  2863.     int i;
  2864.  
  2865.     sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL;
  2866.     inputInfo.numDevices = 0;
  2867.     inputInfo.devices = (DeviceIntPtr)NULL;
  2868.     inputInfo.off_devices = (DeviceIntPtr)NULL;
  2869.     inputInfo.keyboard = (DeviceIntPtr)NULL;
  2870.     inputInfo.pointer = (DeviceIntPtr)NULL;
  2871.     if (spriteTraceSize == 0)
  2872.     {
  2873.     spriteTraceSize = 32;
  2874.     spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr));
  2875.     if (!spriteTrace)
  2876.         FatalError("failed to allocate spriteTrace");
  2877.     }
  2878.     spriteTraceGood = 0;
  2879.     lastEventMask = OwnerGrabButtonMask;
  2880.     filters[MotionNotify] = PointerMotionMask;
  2881.     sprite.win = NullWindow;
  2882.     sprite.current = NullCursor;
  2883.     sprite.hotLimits.x1 = 0;
  2884.     sprite.hotLimits.y1 = 0;
  2885.     sprite.hotLimits.x2 = 0;
  2886.     sprite.hotLimits.y2 = 0;
  2887.     syncEvents.replayDev = (DeviceIntPtr)NULL;
  2888.     while (syncEvents.pending)
  2889.     {
  2890.     QdEventPtr next = syncEvents.pending->next;
  2891.     xfree(syncEvents.pending);
  2892.     syncEvents.pending = next;
  2893.     }
  2894.     syncEvents.pendtail = &syncEvents.pending;
  2895.     syncEvents.playingEvents = FALSE;
  2896.     currentTime.months = 0;
  2897.     currentTime.milliseconds = GetTimeInMillis();
  2898.     for (i = 0; i < DNPMCOUNT; i++)
  2899.     {
  2900.     DontPropagateMasks[i] = 0;
  2901.     DontPropagateRefCnts[i] = 0;
  2902.     }
  2903. }
  2904.  
  2905. int
  2906. ProcSendEvent(client)
  2907.     ClientPtr client;
  2908. {
  2909.     extern int lastEvent;         /* Defined in extension.c */
  2910.     WindowPtr pWin;
  2911.     WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
  2912.     REQUEST(xSendEventReq);
  2913.  
  2914.     REQUEST_SIZE_MATCH(xSendEventReq);
  2915.  
  2916.     /* The client's event type must be a core event type or one defined by an
  2917.     extension. */
  2918.  
  2919.     if ( ! ((stuff->event.u.u.type < LASTEvent) || 
  2920.     ((EXTENSION_EVENT_BASE  <= stuff->event.u.u.type) &&
  2921.     (stuff->event.u.u.type < lastEvent))) )
  2922.     {
  2923.     client->errorValue = stuff->event.u.u.type;
  2924.     return BadValue;
  2925.     }
  2926.     if (stuff->eventMask & ~AllEventMasks)
  2927.     {
  2928.     client->errorValue = stuff->eventMask;
  2929.     return BadValue;
  2930.     }
  2931.  
  2932.     if (stuff->destination == PointerWindow)
  2933.     pWin = sprite.win;
  2934.     else if (stuff->destination == InputFocus)
  2935.     {
  2936.     WindowPtr inputFocus = inputInfo.keyboard->focus->win;
  2937.  
  2938.     if (inputFocus == NoneWin)
  2939.         return Success;
  2940.  
  2941.     /* If the input focus is PointerRootWin, send the event to where
  2942.     the pointer is if possible, then perhaps propogate up to root. */
  2943.        if (inputFocus == PointerRootWin)
  2944.         inputFocus = ROOT;
  2945.  
  2946.     if (IsParent(inputFocus, sprite.win))
  2947.     {
  2948.         effectiveFocus = inputFocus;
  2949.         pWin = sprite.win;
  2950.     }
  2951.     else
  2952.         effectiveFocus = pWin = inputFocus;
  2953.     }
  2954.     else
  2955.     pWin = LookupWindow(stuff->destination, client);
  2956.     if (!pWin)
  2957.     return BadWindow;
  2958.     if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
  2959.     {
  2960.     client->errorValue = stuff->propagate;
  2961.     return BadValue;
  2962.     }
  2963.     stuff->event.u.u.type |= 0x80;
  2964.     if (stuff->propagate)
  2965.     {
  2966.     for (;pWin; pWin = pWin->parent)
  2967.     {
  2968.         if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
  2969.                       NullGrab, 0))
  2970.         return Success;
  2971.         if (pWin == effectiveFocus)
  2972.         return Success;
  2973.         stuff->eventMask &= ~wDontPropagateMask(pWin);
  2974.     }
  2975.     }
  2976.     else
  2977.     (void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
  2978.                     NullGrab, 0);
  2979.     return Success;
  2980. }
  2981.  
  2982. int
  2983. ProcUngrabKey(client)
  2984.     ClientPtr client;
  2985. {
  2986.     REQUEST(xUngrabKeyReq);
  2987.     WindowPtr pWin;
  2988.     GrabRec tempGrab;
  2989.  
  2990.     REQUEST_SIZE_MATCH(xUngrabKeyReq);
  2991.     pWin = LookupWindow(stuff->grabWindow, client);
  2992.     if (!pWin)
  2993.     return BadWindow;
  2994.     if ((stuff->modifiers != AnyModifier) &&
  2995.     (stuff->modifiers & ~AllModifiersMask))
  2996.     {
  2997.     client->errorValue = stuff->modifiers;
  2998.     return BadValue;
  2999.     }
  3000.  
  3001.     tempGrab.resource = client->clientAsMask;
  3002.     tempGrab.device = inputInfo.keyboard;
  3003.     tempGrab.window = pWin;
  3004.     tempGrab.modifiersDetail.exact = stuff->modifiers;
  3005.     tempGrab.modifiersDetail.pMask = NULL;
  3006.     tempGrab.modifierDevice = inputInfo.keyboard;
  3007.     tempGrab.type = KeyPress;
  3008.     tempGrab.detail.exact = stuff->key;
  3009.     tempGrab.detail.pMask = NULL;
  3010.  
  3011.     if (!DeletePassiveGrabFromList(&tempGrab))
  3012.     return(BadAlloc);
  3013.     return(Success);
  3014. }
  3015.  
  3016. int
  3017. ProcGrabKey(client)
  3018.     ClientPtr client;
  3019. {
  3020.     WindowPtr pWin;
  3021.     REQUEST(xGrabKeyReq);
  3022.     GrabPtr grab;
  3023.     DeviceIntPtr keybd = inputInfo.keyboard;
  3024.  
  3025.     REQUEST_SIZE_MATCH(xGrabKeyReq);
  3026.     if ((stuff->pointerMode != GrabModeSync) &&
  3027.     (stuff->pointerMode != GrabModeAsync))
  3028.     {
  3029.     client->errorValue = stuff->pointerMode;
  3030.         return BadValue;
  3031.     }
  3032.     if ((stuff->keyboardMode != GrabModeSync) &&
  3033.     (stuff->keyboardMode != GrabModeAsync))
  3034.     {
  3035.     client->errorValue = stuff->keyboardMode;
  3036.         return BadValue;
  3037.     }
  3038.     if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
  3039.      (stuff->key < keybd->key->curKeySyms.minKeyCode))
  3040.     && (stuff->key != AnyKey))
  3041.     {
  3042.     client->errorValue = stuff->key;
  3043.         return BadValue;
  3044.     }
  3045.     if ((stuff->modifiers != AnyModifier) &&
  3046.     (stuff->modifiers & ~AllModifiersMask))
  3047.     {
  3048.     client->errorValue = stuff->modifiers;
  3049.     return BadValue;
  3050.     }
  3051.     pWin = LookupWindow(stuff->grabWindow, client);
  3052.     if (!pWin)
  3053.     return BadWindow;
  3054.  
  3055.     grab = CreateGrab(client->index, keybd, pWin, 
  3056.     (Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
  3057.     (Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
  3058.     keybd, stuff->modifiers, KeyPress, stuff->key, NullWindow, NullCursor);
  3059.     if (!grab)
  3060.     return BadAlloc;
  3061.     return AddPassiveGrabToList(grab);
  3062. }
  3063.  
  3064. int
  3065. ProcGrabButton(client)
  3066.     ClientPtr client;
  3067. {
  3068.     WindowPtr pWin, confineTo;
  3069.     REQUEST(xGrabButtonReq);
  3070.     CursorPtr cursor;
  3071.     GrabPtr grab;
  3072.  
  3073.     REQUEST_SIZE_MATCH(xGrabButtonReq);
  3074.     if ((stuff->pointerMode != GrabModeSync) &&
  3075.     (stuff->pointerMode != GrabModeAsync))
  3076.     {
  3077.     client->errorValue = stuff->pointerMode;
  3078.         return BadValue;
  3079.     }
  3080.     if ((stuff->keyboardMode != GrabModeSync) &&
  3081.     (stuff->keyboardMode != GrabModeAsync))
  3082.     {
  3083.     client->errorValue = stuff->keyboardMode;
  3084.         return BadValue;
  3085.     }
  3086.     if ((stuff->modifiers != AnyModifier) &&
  3087.     (stuff->modifiers & ~AllModifiersMask))
  3088.     {
  3089.     client->errorValue = stuff->modifiers;
  3090.     return BadValue;
  3091.     }
  3092.     if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
  3093.     {
  3094.     client->errorValue = stuff->ownerEvents;
  3095.     return BadValue;
  3096.     }
  3097.     if (stuff->eventMask & ~PointerGrabMask)
  3098.     {
  3099.     client->errorValue = stuff->eventMask;
  3100.         return BadValue;
  3101.     }
  3102.     pWin = LookupWindow(stuff->grabWindow, client);
  3103.     if (!pWin)
  3104.     return BadWindow;
  3105.     if (stuff->confineTo == None)
  3106.     confineTo = NullWindow;
  3107.     else
  3108.     {
  3109.     confineTo = LookupWindow(stuff->confineTo, client);
  3110.     if (!confineTo)
  3111.         return BadWindow;
  3112.     }
  3113.     if (stuff->cursor == None)
  3114.     cursor = NullCursor;
  3115.     else
  3116.     {
  3117.     cursor = (CursorPtr)LookupIDByType(stuff->cursor, RT_CURSOR);
  3118.     if (!cursor)
  3119.     {
  3120.         client->errorValue = stuff->cursor;
  3121.         return BadCursor;
  3122.     }
  3123.     }
  3124.  
  3125.     grab = CreateGrab(client->index, inputInfo.pointer, pWin, 
  3126.     permitOldBugs ? (Mask)(stuff->eventMask |
  3127.                    ButtonPressMask | ButtonReleaseMask) :
  3128.             (Mask)stuff->eventMask,
  3129.     (Bool)stuff->ownerEvents, (Bool) stuff->keyboardMode,
  3130.     (Bool)stuff->pointerMode, inputInfo.keyboard, stuff->modifiers,
  3131.     ButtonPress, stuff->button, confineTo, cursor);
  3132.     if (!grab)
  3133.     return BadAlloc;
  3134.     return AddPassiveGrabToList(grab);
  3135. }
  3136.  
  3137. int
  3138. ProcUngrabButton(client)
  3139.     ClientPtr client;
  3140. {
  3141.     REQUEST(xUngrabButtonReq);
  3142.     WindowPtr pWin;
  3143.     GrabRec tempGrab;
  3144.  
  3145.     REQUEST_SIZE_MATCH(xUngrabButtonReq);
  3146.     if ((stuff->modifiers != AnyModifier) &&
  3147.     (stuff->modifiers & ~AllModifiersMask))
  3148.     {
  3149.     client->errorValue = stuff->modifiers;
  3150.     return BadValue;
  3151.     }
  3152.     pWin = LookupWindow(stuff->grabWindow, client);
  3153.     if (!pWin)
  3154.     return BadWindow;
  3155.  
  3156.     tempGrab.resource = client->clientAsMask;
  3157.     tempGrab.device = inputInfo.pointer;
  3158.     tempGrab.window = pWin;
  3159.     tempGrab.modifiersDetail.exact = stuff->modifiers;
  3160.     tempGrab.modifiersDetail.pMask = NULL;
  3161.     tempGrab.modifierDevice = inputInfo.keyboard;
  3162.     tempGrab.type = ButtonPress;
  3163.     tempGrab.detail.exact = stuff->button;
  3164.     tempGrab.detail.pMask = NULL;
  3165.  
  3166.     if (!DeletePassiveGrabFromList(&tempGrab))
  3167.     return(BadAlloc);
  3168.     return(Success);
  3169. }
  3170.  
  3171. void
  3172. DeleteWindowFromAnyEvents(pWin, freeResources)
  3173.     WindowPtr        pWin;
  3174.     Bool        freeResources;
  3175. {
  3176.     WindowPtr        parent;
  3177.     DeviceIntPtr    mouse = inputInfo.pointer;
  3178.     DeviceIntPtr    keybd = inputInfo.keyboard;
  3179.     FocusClassPtr    focus = keybd->focus;
  3180.     OtherClientsPtr    oc;
  3181.     GrabPtr        passive;
  3182.  
  3183.  
  3184.     /* Deactivate any grabs performed on this window, before making any
  3185.     input focus changes. */
  3186.  
  3187.     if (mouse->grab &&
  3188.     ((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
  3189.     (*mouse->DeactivateGrab)(mouse);
  3190.  
  3191.     /* Deactivating a keyboard grab should cause focus events. */
  3192.  
  3193.     if (keybd->grab && (keybd->grab->window == pWin))
  3194.     (*keybd->DeactivateGrab)(keybd);
  3195.  
  3196.     /* If the focus window is a root window (ie. has no parent) then don't 
  3197.     delete the focus from it. */
  3198.     
  3199.     if ((pWin == focus->win) && (pWin->parent != NullWindow))
  3200.     {
  3201.     int focusEventMode = NotifyNormal;
  3202.  
  3203.      /* If a grab is in progress, then alter the mode of focus events. */
  3204.  
  3205.     if (keybd->grab)
  3206.         focusEventMode = NotifyWhileGrabbed;
  3207.  
  3208.     switch (focus->revert)
  3209.     {
  3210.     case RevertToNone:
  3211.         DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
  3212.         focus->win = NoneWin;
  3213.         focus->traceGood = 0;
  3214.         break;
  3215.     case RevertToParent:
  3216.         parent = pWin;
  3217.         do
  3218.         {
  3219.         parent = parent->parent;
  3220.         focus->traceGood--;
  3221.         } while (!parent->realized);
  3222.         DoFocusEvents(keybd, pWin, parent, focusEventMode);
  3223.         focus->win = parent;
  3224.         focus->revert = RevertToNone;
  3225.         break;
  3226.     case RevertToPointerRoot:
  3227.         DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
  3228.         focus->win = PointerRootWin;
  3229.         focus->traceGood = 0;
  3230.         break;
  3231.     }
  3232.     }
  3233.  
  3234.     if (mouse->valuator->motionHintWindow == pWin)
  3235.     mouse->valuator->motionHintWindow = NullWindow;
  3236.  
  3237.     if (freeResources)
  3238.     {
  3239.     if (pWin->dontPropagate)
  3240.         DontPropagateRefCnts[pWin->dontPropagate]--;
  3241.     while (oc = wOtherClients(pWin))
  3242.         FreeResource(oc->resource, RT_NONE);
  3243.     while (passive = wPassiveGrabs(pWin))
  3244.         FreeResource(passive->resource, RT_NONE);
  3245.      }
  3246. #ifdef XINPUT
  3247.     DeleteWindowFromAnyExtEvents(pWin, freeResources);
  3248. #endif
  3249. }
  3250.  
  3251. /* Call this whenever some window at or below pWin has changed geometry */
  3252.  
  3253. /*ARGSUSED*/
  3254. void
  3255. CheckCursorConfinement(pWin)
  3256.     WindowPtr pWin;
  3257. {
  3258.     GrabPtr grab = inputInfo.pointer->grab;
  3259.     WindowPtr confineTo;
  3260.  
  3261.     if (grab && (confineTo = grab->confineTo))
  3262.     {
  3263.     if (!(* confineTo->drawable.pScreen->RegionNotEmpty)
  3264.             (&confineTo->borderSize))
  3265.         (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer);
  3266.     else if ((pWin == confineTo) || IsParent(pWin, confineTo))
  3267.         ConfineCursorToWindow(confineTo, TRUE);
  3268.     }
  3269. }
  3270.  
  3271. Mask
  3272. EventMaskForClient(pWin, client)
  3273.     WindowPtr        pWin;
  3274.     ClientPtr        client;
  3275. {
  3276.     register OtherClientsPtr    other;
  3277.  
  3278.     if (wClient (pWin) == client)
  3279.     return pWin->eventMask;
  3280.     for (other = wOtherClients(pWin); other; other = other->next)
  3281.     {
  3282.     if (SameClient(other, client))
  3283.         return other->mask;
  3284.     }
  3285.     return 0;
  3286. }
  3287.  
  3288. int
  3289. ProcRecolorCursor(client)
  3290.     ClientPtr client;
  3291. {
  3292.     CursorPtr pCursor;
  3293.     int        nscr;
  3294.     ScreenPtr    pscr;
  3295.     REQUEST(xRecolorCursorReq);
  3296.  
  3297.     REQUEST_SIZE_MATCH(xRecolorCursorReq);
  3298.     pCursor = (CursorPtr)LookupIDByType(stuff->cursor, RT_CURSOR);
  3299.     if ( !pCursor) 
  3300.     {
  3301.     client->errorValue = stuff->cursor;
  3302.     return (BadCursor);
  3303.     }
  3304.  
  3305.     pCursor->foreRed = stuff->foreRed;
  3306.     pCursor->foreGreen = stuff->foreGreen;
  3307.     pCursor->foreBlue = stuff->foreBlue;
  3308.  
  3309.     pCursor->backRed = stuff->backRed;
  3310.     pCursor->backGreen = stuff->backGreen;
  3311.     pCursor->backBlue = stuff->backBlue;
  3312.  
  3313.     for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
  3314.     {
  3315.     pscr = screenInfo.screens[nscr];
  3316.     ( *pscr->RecolorCursor)(pscr, pCursor,
  3317.                 (pCursor == sprite.current) &&
  3318.                 (pscr == sprite.hotPhys.pScreen));
  3319.     }
  3320.     return (Success);
  3321. }
  3322.  
  3323. void
  3324. WriteEventsToClient(pClient, count, events)
  3325.     ClientPtr    pClient;
  3326.     int        count;
  3327.     xEvent    *events;
  3328. {
  3329.     if(pClient->swapped)
  3330.     {
  3331.         int    i;
  3332.         xEvent    eventTo, *eventFrom;
  3333.  
  3334.     for(i = 0; i < count; i++)
  3335.     {
  3336.         eventFrom = &events[i];
  3337.         /* Remember to strip off the leading bit of type in case
  3338.            this event was sent with "SendEvent." */
  3339.         (*EventSwapVector[eventFrom->u.u.type & 0177])
  3340.         (eventFrom, &eventTo);
  3341.         (void)WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo);
  3342.     }
  3343.     }
  3344.  
  3345.     else
  3346.     {
  3347.     (void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events);
  3348.     }
  3349. }
  3350.